Reputation: 56547
I have the following piece of code, in which I wrap a generic (POD) type into a (template) class, and define an inner template conversion operator so that I'm able to have implicit conversions between compatible (but different) types. I hope the code is quite self-explanatory. Under no circumstance I can figure out why converting Foo<double>
to another POD works fine, but a conversion to std::complex<double>
(typedefed here as cplx
) fails miserably with
error: call of overloaded 'complex(Foo<double>&)' is ambiguous
cplx z = (cplx)a;
Any ideas? Code below:
#include <iostream>
#include <complex>
using cplx = std::complex<double>;
template <typename T>
class Foo // wrapper class for a POD
{
T val_; // this is the wrapped value
public:
Foo(T val = {}): val_(val) {};
template<typename S> // conversion operator
operator S ()
{
std::cout << "Calling conversion operator" << std::endl;
return val_;
}
// stream operator
friend std::ostream &operator<<(std::ostream &os, const Foo &rhs)
{
return os << rhs.val_;
}
};
int main()
{
Foo<double> a = 10.1;
// OK, calling the conversion operator double -> int
int i = 2 + (int)a;
// Calling conversion operator double -> cplx
// this line DOES NOT compile, why?!
// cplx z = (cplx)a;
}
Upvotes: 2
Views: 1495
Reputation: 6214
There are double
, float
, and long double
constructors to std::complex
. The compiler doesn't know which to use; it can instantiate Foo::operator S
with any of them.
If you pick one of them, the compiler can fill in the rest:
cplx z = (cplx)(double)a;
Upvotes: 2