Почему std::vector<T> v{1, 2, 3} и std::vector<T> v = {1, 2, 3} вызывают разные конструкторы, когда T неявно преобразуетC++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Почему std::vector<T> v{1, 2, 3} и std::vector<T> v = {1, 2, 3} вызывают разные конструкторы, когда T неявно преобразует

Сообщение Anonymous »

Вопрос — см. Compiler Explorer
Если я создаю std::vector и инициализирую его двумя способами, оба вызывают std::initializer_list конструктор.

Код: Выделить всё

std::vector  v1{1, 2, 3};     // Calls vector(initializer_list< int >)
std::vector  v2 = {1, 2, 3};  // Calls vector(initializer_list< int >)
Но если я использую класс, который неявно преобразует из int:

Код: Выделить всё

struct Imp { Imp(int) {} };
Затем второй метод инициализации вызывает конструктор, который принимает пару итераторов.

Код: Выделить всё

std::vector  v3{1, 2, 3};     // Calls vector(initializer_list< Imp >)
std::vector  v4 = {1, 2, 3};  // Calls vector(const int*, const int* ) ???
Это происходит только при использовании GCC 14.2. При использовании Clang 19.1 или MSVC 19.40 и v3, и v4 вызывают конструктор Initializer_list. Уровень оптимизации не имеет значения
Почему синтаксис = { вызывает вектор(const int*, const int*) в GCC?
Дальнейшее исследование
Я попробовал создать собственный шаблон класса с обоими конструкторами:

Код: Выделить всё

template 
struct Custom {
Custom(std::initializer_list) {}
Custom(const int*, const int*)   {}
};
Теперь оба синтаксиса {} и = {} вызывают конструктор инициализатора_list в GCC.

Код: Выделить всё

Custom       v5{1, 2, 3};     // Calls Custom(initializer_list< Imp >)
Custom       v6 = {1, 2, 3};  // Calls Custom(initializer_list< Imp >)
Что действительно сбивает с толку, так это то, что я специализируюсь на std::vector для своего неявно преобразующего типа Imp. Тогда есть три случая:
Случай 1 — предоставить только инициализатор_list ctor

Код: Выделить всё

template 
struct std::vector {
vector(initializer_list)   {}
};
Результат — оба синтаксиса вызывают предоставленный ctor

Код: Выделить всё

std::vector v7{1, 2, 3};      // Calls vector(initializer_list< Imp >)
std::vector v8 = {1, 2, 3};   // Calls vector(initializer_list< Imp >)
Случай 2 — укажите только const int* ctor

Код: Выделить всё

template 
struct std::vector {
vector(const int*, const int*)   {}
};
Результат — оба синтаксиса не удалось скомпилировать (нет соответствующего ctor)

Код: Выделить всё

std::vector v9{1, 2, 3};      // Error - no matching ctor
std::vector vA = {1, 2, 3};   // Error - no matching ctor
Случай 3 — укажите оба фактора

Код: Выделить всё

template 
struct std::vector {
vector(initializer_list)   {}
vector(const int*, const int*)   {}
};
Результат. Синтаксис { вызывает инициализатор_list, а = {}< Синтаксис /code> вызывает const int* ctor

Код: Выделить всё

std::vector vB{1, 2, 3};      // Calls vector(initializer_list< Imp >)
std::vector vC = {1, 2, 3};   // Calls vector(const int*, const int*) ???
Здесь я заблудился.

В случай 3 как предоставление конструктора Initializer_list позволяет вызывать конструктор const int*?

Подробнее здесь: https://stackoverflow.com/questions/793 ... -different
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»