简体   繁体   English

模板的类型转换

[英]type conversion for templates

I have a wrapper class template and want to have implicit conversion to the wrapped type in order to use existing library functions: 我有一个包装器类模板,并希望隐式转换为包装器类型,以便使用现有的库函数:

#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;
}

The f(std::complex<T>) is not used for f(ca) because implicit conversion is not considered during template argument deduction (see the generated error msg. here ). f(std::complex<T>)不用于f(ca)因为在模板参数推导过程中未考虑隐式转换(请参见此处生成的错误msg。)。

In the real code f(...) is replaced by library functions eg from the <complex> header, so it can't be modified. 在实际代码中, f(...)被库函数代替,例如从<complex>头开始,因此无法对其进行修改。

If I inherit A from T (as suggested by the error message) then f(ca) compiles. 如果我从T继承A (如错误消息所建议),则f(ca)编译。 But then A is not defined for built-in types (you can't inherit from them). 但是然后没有为内置类型定义A (您不能从它们继承)。 Also, that would give all the functionality of complex<double> to A<complex<double>> which I want to avoid. 另外,这将把complex<double>所有功能赋予A<complex<double>> ,这是我要避免的。

Is there any workaround for this? 有什么解决方法吗?

To resolve the "doesn't work for built-in types" problem, you can use a template specialization. 要解决“不适用于内置类型”的问题,可以使用模板专门化。 The std::complex<> version uses inheritance. 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) {}
};

If inheritance is not acceptable, the only approach I am aware of is to define functions that take A<> as an argument. 如果继承是不可接受的,我知道的唯一方法是定义以A<>作为参数的函数。 However, you can simplify the task by defining the functions within A<> itself, and thus leveraging a simplified syntax for the template argument, and argument dependent lookup for function call invocation. 但是,您可以通过在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; }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM