模板的类型转换
type conversion for templates
我有一个包装器 class 模板,想要隐式转换为包装类型以便使用现有的库函数:
#include <complex>
double f(double x) { return 1.; }
template <typename T>
std::complex<T> f(std::complex<T> x) { return std::complex<T>(); }
template <typename T>
class A {
T _x;
public:
A(const T& x) : _x(x) {}
operator T() { return _x; }
};
int main() {
A<double> da(1.);
A<std::complex<double>> ca({1.,1.});
f(da); // OK
f(ca); // error
return 1;
}
f(std::complex<T>)
不用于 f(ca)
,因为在模板参数推导期间不考虑隐式转换(请参阅生成的错误消息。here)。
在实际代码中 f(...)
被库函数替换,例如来自 <complex>
header,所以无法修改。
如果我从 T
继承 A
(如错误消息所建议的那样),则 f(ca)
会编译。但是 A
没有为 built-in 类型定义(你不能从它们继承)。此外,这会将 complex<double>
的所有功能赋予 A<complex<double>>
我想避免的功能。
有什么解决方法吗?
要解决 "doesn't work for built-in types" 问题,您可以使用模板专业化。 std::complex<>
版本使用继承。
template <typename T>
class A {
T _x;
public:
A(const T& x) : _x(x) {}
operator const T &() const { return _x; }
operator T &() { return _x; }
};
template <typename D>
class A<std::complex<D>> : public std::complex<D> {
typedef std::complex<D> T;
public:
A(const T& x) : T(x) {}
};
如果继承是不可接受的,我知道的唯一方法是定义以 A<>
作为参数的函数。但是,您可以通过在 A<>
本身内定义函数来简化任务,从而利用模板参数的简化语法和函数调用调用的参数依赖查找。
template <typename T>
class A {
T _x;
friend A f(A x) { return f(x._x); }
public:
A(const T& x) : _x(x) {}
operator const T &() const { return _x; }
operator T &() { return _x; }
};
我有一个包装器 class 模板,想要隐式转换为包装类型以便使用现有的库函数:
#include <complex>
double f(double x) { return 1.; }
template <typename T>
std::complex<T> f(std::complex<T> x) { return std::complex<T>(); }
template <typename T>
class A {
T _x;
public:
A(const T& x) : _x(x) {}
operator T() { return _x; }
};
int main() {
A<double> da(1.);
A<std::complex<double>> ca({1.,1.});
f(da); // OK
f(ca); // error
return 1;
}
f(std::complex<T>)
不用于 f(ca)
,因为在模板参数推导期间不考虑隐式转换(请参阅生成的错误消息。here)。
在实际代码中 f(...)
被库函数替换,例如来自 <complex>
header,所以无法修改。
如果我从 T
继承 A
(如错误消息所建议的那样),则 f(ca)
会编译。但是 A
没有为 built-in 类型定义(你不能从它们继承)。此外,这会将 complex<double>
的所有功能赋予 A<complex<double>>
我想避免的功能。
有什么解决方法吗?
要解决 "doesn't work for built-in types" 问题,您可以使用模板专业化。 std::complex<>
版本使用继承。
template <typename T>
class A {
T _x;
public:
A(const T& x) : _x(x) {}
operator const T &() const { return _x; }
operator T &() { return _x; }
};
template <typename D>
class A<std::complex<D>> : public std::complex<D> {
typedef std::complex<D> T;
public:
A(const T& x) : T(x) {}
};
如果继承是不可接受的,我知道的唯一方法是定义以 A<>
作为参数的函数。但是,您可以通过在 A<>
本身内定义函数来简化任务,从而利用模板参数的简化语法和函数调用调用的参数依赖查找。
template <typename T>
class A {
T _x;
friend A f(A x) { return f(x._x); }
public:
A(const T& x) : _x(x) {}
operator const T &() const { return _x; }
operator T &() { return _x; }
};