Равномерная инициализация происходит неявно, даже если оператор int cast объявлен с явным ключевым словом.Какова причина? - PullRequest
2 голосов
/ 26 сентября 2019
#include <iostream>

using namespace std;

class Test
{
private:
    mutable int val{};
public:
    static constexpr int MAX{ 5 };
public:
    Test() = default;
    Test(int i) : val{ i } {}
    ~Test() { cout << "~Test()" << endl; }

    explicit operator int() const { return val; }   // int()변환 연산자 오버로딩 (반환형식을 기재하지 않는다.)

    void print() const
    {
        ++val;  // mutable 형식이기 때문에 수정가능
        cout << val << endl;
    }
};

int main()
{
    Test t{ 10 };
    int i = static_cast<int>(t);    // int()변환 연산자가 explicit이라 명시적으로 타입캐스팅을 해주어야한다.
    int j{ t };                     // 근데 얘는 왜 될까..??
}

"Равномерная инициализация происходит неявно, даже если оператор int cast объявлен с явным ключевым словом. В чем причина?"

1 Ответ

1 голос
/ 26 сентября 2019

int j{ t }; выполняет прямую инициализацию , что учитывает explicit функцию преобразования.

Прямая инициализация более разрешительна, чем инициализация копирования: только инициализация копирования учитываетнеявные конструкторы и неявные пользовательские функции преобразования, в то время как прямая инициализация учитывает все конструкторы и все пользовательские функции преобразования.

С другой стороны, копировать инициализацию учитывает только неявные функции преобразования.Тогда int j = t; плохо сформирован.

Из стандарта [class.conv.fct] / 2

Функция преобразования может быть явной ( [dcl.fct.spec] ), в этом случае он рассматривается только как преобразование, определенное пользователем для прямой инициализации ( [dcl.init] ).В противном случае пользовательские преобразования не ограничиваются использованием в присваиваниях и инициализациях.[Пример:

class Y { };
struct Z {
  explicit operator Y() const;
};

void h(Z z) {
  Y y1(z);          // OK: direct-initialization
  Y y2 = z;         // ill-formed: copy-initialization
  Y y3 = (Y)z;      // OK: cast notation
}

void g(X a, X b) {
  int i = (a) ? 1+a : 0;
  int j = (a&&b) ? a+b : i;
  if (a) {
  }
}

- конец примера]

...