инициализация копирования — преобразование из int в нескалярный тип

Я хотел бы знать, как я должен определить класс my_int, чтобы приведение от Int до std::complex< my_int > делается компилятором, а не вручную мной.

Следующая программа не компилируется, если 4 не приведен к «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;
}

Я знаю, что если вы инициализируете ci с std::complex<my_int> ci(4) это работает, но я хочу, чтобы он работал с инициализацией копирования.

6

Решение

Кажущаяся проблема в том, что более одного пользовательского преобразования не допускается в контексте инициализации копирования, и это можно решить с помощью контекста прямой инициализации, например,

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

тем не мение, есть еще одна скрытая проблема: эффект создания шаблона комплекса для любого типа, кроме float, double или же long double не указано, так что вы должны явно специализировать его, как указал StoryTeller в комментарии.

1

Другие решения

Вы можете определить свой сложный класс и написать конструктор таким образом.

  Complex(int re, int im = 0);

В этом случае компилятор неявно преобразует int в сложный на

Complex c = 5;
2