vsoftco
vsoftco

Reputation: 56547

conversion operator to std::complex<double>

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

Answers (1)

user3553031
user3553031

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

Related Questions