Когда использовать явный спецификатор для конструкторов с несколькими аргументами?

Я недавно узнал о explicit спецификатор.

Предположим, у нас есть:

f( W, W, W );

Теперь, если мы сделаем

f( 42, 3.14, "seven" );

Компилятор попытается выполнить следующие неявные преобразования:

f( W(42), W(3.14), W("seven") );

Если мы определили соответствующие конструкторы для W, а именно:

W(int);
W(double);
W(std::string);

…это удастся.

Однако, если мы сделаем первый явным:

explicit W(int);

… это отключает неявное преобразование.

Теперь вы должны написать:

f( W(42), 3.14, "seven" );

то есть вынуждает вас явно указывать конверсию

Теперь к вопросу:

Можно написать:

explicit W(int,int); // 2 arguments!

Это компилируется!

Но я не вижу никакого соответствующего сценария, который мог бы потребовать этот синтаксис.

Кто-нибудь может привести минимальный пример?

6

Решение

Если ваш конструктор является явным, и класс не предоставляет неявный конструктор, принимающий initializer_list<T>, то вы не можете скопировать список инициализировать экземпляр.

W w = {1,2}; // compiles without explicit, but not with

Простой живой пример

#include <iostream>

class A
{
public:
explicit A(int, int) {}
};

class B
{
public:
B(int, int) {}
};

int main()
{
B b = {1,2};
A a = {1,2};
}

Цитаты из стандарта:

8.5 / 16

— Если инициализатором является (не заключенный в скобки) фигурный список инициализации,
объект или ссылка инициализируются списком (8.5.4).

8.5.4 / 3

Инициализация списка объекта или ссылки типа T определяется как
следует: …

В противном случае, если T является типом класса, учитываются конструкторы.
перечислены соответствующие конструкторы и выбран лучший
через разрешение перегрузки (13.3, 13.3.1.7). Если сужение
преобразование (см. ниже) требуется для преобразования любого из аргументов,
программа плохо сформирована.

11

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


По вопросам рекламы [email protected]