Type conversion for templates

I have a wrapper class template and want to have an implicit conversion to a wrapped type in order to use the 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; } 

f(std::complex<T>) not used for f(ca) because the implicit conversion is not taken into account when outputting the template argument (see the generated msg error. here ).

In real code, f(...) is replaced by library functions, for example. from the <complex> header, so it cannot be changed.

If I inherit A from T (as suggested by the error message), then f(ca) compiles. But then A not defined for built-in types (you cannot inherit them). In addition, this will give all the functionality of complex<double> to A<complex<double>> , which I want to avoid.

Is there a workaround for this?

+8
c ++ type-conversion templates
source share
1 answer

To solve the "does not work for built-in types" problem, you can use specialized specialization. The std::complex<> version uses inheritance.

 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 unacceptable, the only approach I know is to define functions that take A<> as an argument. However, you can simplify the task by defining the functions inside A<> and, thus, using the simplified syntax of the template argument and argument-dependent search for calling the function call.

 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; } }; 
+4
source share

All Articles