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

#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),因为在模板参数推导过程中不考虑隐式转换(请参见生成的错误msg。here)。

在实际代码中f(...)被库函数例如从<complex> header 中删除,因此无法对其进行修改。

如果我从A继承T(如错误消息所建议),则f(ca)会编译。但是然后A没有为内置类型定义(您不能从它们继承)。另外,这将使complex<double>的所有功能都变为我想要避免的A<complex<double>>

有什么解决方法吗?

最佳答案

要解决“不适用于内置类型”的问题,可以使用模板专门化。 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; }
};

关于c++ - 模板的类型转换,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29760396/

10-11 23:02
查看更多