Matthias Möller
Matthias Möller

Reputation: 79

Type conversion from std::complex<MyType> to std::complex<double>

I have a class MyType that implements a user-defined arithmetic type. This class provides the following conversion operator

struct MyType 
{ ...
  operator double()
  { 
    return to_double(); // This converts my type to a double value
  }
... };

Using this class as follows works fine:

double d = MyType(1);

However, using this class as type within std::complex, e.g.

#include <complex>
std::complex<double> c = std::complex<MyType>(1,1);

fails with the following compiler error:

error: conversion from 'std::complex<MyType>' to non-scalar type 'std::complex<double>' requested

Any help to solve this problem is appreciated.

Matthias

Upvotes: 2

Views: 860

Answers (2)

Stefan Scheller
Stefan Scheller

Reputation: 953

Does this (not particularly elegant) workaround help?

std::complex<MyType> dummy(1,1);
std::complex<double> c1(
    static_cast<double>(dummy.real()), static_cast<double>(dummy.imag()));

I tried all kinds of different constructors and assignment operators of std::complex but did not find a more "implicit" way of converting.

I think this is related: Why doesn't a conversion function work with std::string?

Upvotes: 0

Jarod42
Jarod42

Reputation: 217235

The specializations std::complex<float>, std::complex<double>, and std::complex<long double> are LiteralTypes for representing and manipulating complex numbers.

The effect of instantiating the template complex for any other type is unspecified.

So std::complex<MyType> is "problematic"...

Ignoring that part,

whereas std::complex<T> has generic converting constructor, specialization std::complex<double> only provide conversions from other floating complex versions.

But operator= allows generic conversion for all versions (Only Msvc accepts the code though).

You have to provide your own (explicit/named) conversion function:

std::complex<double> to_complex_double(std::complex<MyType>& c)
{
#if 0
     std::complex<double> res;
     res = c; // gcc/clang doesn't accept that.
     return res;
#else
     return {c.real(), c.imag()};
#endif
}

Upvotes: 3

Related Questions