Почему я не могу использовать заключенный в фигурные скобки список как операнд перегруженного оператора?
Я работаю с набором пользовательских библиотек 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
Я вижу, что конструктор списка инициализатора работает просто замечательно, как и перегруженный +
оператор. Вполне допустимо вызывать функцию, которая принимает два InitListConstructible
s, где второе инициализируется из заключенного в скобки выражения.
Тем не менее, линия
auto error = lhs + { 1, 2, 3 };
не компилируется и выдает ошибку об отсутствующем первичном выражении. Это приводит меня к мысли, что синтаксис языка просто не допускает подобных вещей.
Мои вопросы следующие:
- Является ли мой анализ проблемы - что языковая спецификация просто не допускает заключенные в скобки списки в контекстах выражений - правильным?
- Есть ли фундаментальная причина, почему это не разрешено, учитывая, что заключенное в скобки выражение может иметь свой тип, выведенный из типа аргумента
operator+
? Я подозреваю, что это связано с тем, что каждое выражение в C++ должно иметь четко определенный тип, который не зависит от контекста, и если это правильно, я был бы признателен за подтверждение.