c++c++11templatesc++14copy-initialization

copy initialization - conversion from 'int' to non-scalar type


I would like to know how I should define the class my_int so that the cast from int to std::complex< my_int > is done by the compiler instead of manually by me.

The following program does not compile if 4 is not casted to "my_int"

// Example program
#include <iostream>
#include <string>
#include <complex>

struct my_int
{
    my_int() : _i(0) {}
    my_int(const my_int& mi) : _i(mi._i) {}

    my_int(int i) : _i(i) {}
    operator int(){return _i;}

    int _i;
};

std::ostream& operator<<(std::ostream& os, const my_int& mi)
{
    os << mi._i;
    return os;
}

int main()
{
  std::complex<my_int> ci = 4; // Casting 4 to my_int works

  std::cout << ci;
}

I know that if you initialize ci with std::complex<my_int> ci(4) it works, but I want it to work with copy initialization.


Solution

  • The seeming problem is that more than one user-defined conversion is not allowed in the copy-initialization context, and it can be solved by using direct-initialization context, e.g.

    std::complex<my_int> ci{4}; 
    

    However, there is another hidden problem: the effect of instantiating the template complex for any type other than float, double or long double is unspecified, so you have to explicitly specialize it, as StoryTeller pointed out in the comment.