模板的类型转换

M Z*_*nyi 8 c++ templates type-conversion

我有一个包装类模板,并希望隐式转换为包装类型,以便使用现有的库函数:

#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;
}
Run Code Online (Sandbox Code Playgroud)

f(std::complex<T>)不使用f(ca),因为模板参数推导过程中的隐式转换不考虑(查看生成的错误味精.这里).

在实际代码f(...)中,库函数例如从<complex>头部替换,因此不能修改.

如果我继承AT(由错误消息作为所建议的),然后f(ca)编译.但是A没有为内置类型定义(你不能从它们继承).此外,将给予的所有功能complex<double>,以A<complex<double>>我想避免.

这有什么解决方法吗?

jxh*_*jxh 4

要解决“不适用于内置类型”问题,您可以使用模板专门化。该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) {}
};
Run Code Online (Sandbox Code Playgroud)

如果继承是不可接受的,我知道的唯一方法是定义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; }
};
Run Code Online (Sandbox Code Playgroud)