Почему я не могу использовать заключенный в фигурные скобки список как операнд перегруженного оператора?

Я работаю с набором пользовательских библиотек C++, которые предоставляют тип, представляющий последовательность. Там перегружен operator+ который принимает две последовательности и объединяет их, а инициализатор принимает std::intializer_list это можно использовать для инициализации последовательности списком значений. Каждая из этих функций хорошо работает сама по себе, но по какой-то причине они плохо взаимодействуют друг с другом.

Вот сокращенный тестовый пример, демонстрирующий проблему:

#include <iostream>
#include <initializer_list>
using namespace std;

struct InitListConstructible {
    InitListConstructible() = default;

    InitListConstructible(std::initializer_list<int> elems) {
        // do something
    }
};

InitListConstructible operator+ (InitListConstructible lhs,
                                 InitListConstructible rhs) {
    return {};                                  
}

int main() {
    /* Totally fine - use initializer list constructor. */
    InitListConstructible lhs = { 1, 2, 3 };

    /* Totally fine - use overloaded + operator. */
    auto legit = lhs + lhs;

    /* Totally fine - second argument constructed from initializer list. */
    freeFunction(lhs, { 1, 2, 3 });

    /* Totally fine - explicit call to operator+. */
    auto alsoLegit = operator+ (lhs, { 1, 2, 3 });

    /* Not okay - reports error about expected primary-expression. */
    auto error = lhs + { 1, 2, 3 };

    return 0;
}

Здесь тип InitListConstructible простая структура, которая имеет конструктор по умолчанию и конструктор списка инициализатора. Также есть перегруженный + оператор, который принимает в два InitListConstructible возражает и возвращает треть.

В mainЯ вижу, что конструктор списка инициализатора работает просто замечательно, как и перегруженный + оператор. Вполне допустимо вызывать функцию, которая принимает два InitListConstructibles, где второе инициализируется из заключенного в скобки выражения.

Тем не менее, линия

auto error = lhs + { 1, 2, 3 };

не компилируется и выдает ошибку об отсутствующем первичном выражении. Это приводит меня к мысли, что синтаксис языка просто не допускает подобных вещей.

Мои вопросы следующие:

  1. Является ли мой анализ проблемы - что языковая спецификация просто не допускает заключенные в скобки списки в контекстах выражений - правильным?
  2. Есть ли фундаментальная причина, почему это не разрешено, учитывая, что заключенное в скобки выражение может иметь свой тип, выведенный из типа аргумента operator+? Я подозреваю, что это связано с тем, что каждое выражение в C++ должно иметь четко определенный тип, который не зависит от контекста, и если это правильно, я был бы признателен за подтверждение.

0 ответов

Другие вопросы по тегам