为什么我不能使用括号括起的列表作为重载运算符的操作数?

tem*_*def 6 c++ operator-overloading initializer-list language-lawyer c++11

我正在使用一组自定义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;
}
Run Code Online (Sandbox Code Playgroud)

这里,类型InitListConstructible是一个简单的结构,它有一个默认的构造函数和一个初始化列表构造函数.还有一个重载的+运算符,它接收两个InitListConstructible对象并返回第三个对象.

main,我可以看到初始化列表构造函数工作得很好,重载+运算符也是如此.它完全合法地调用一个函数,它接受两个InitListConstructibles,其中第二个从括号括起的表达式初始化.

但是,行

auto error = lhs + { 1, 2, 3 };
Run Code Online (Sandbox Code Playgroud)

不编译,它报告有关缺少的主表达式的错误.这让我相信语言语法不允许这样的事情.

我的问题如下:

  1. 我对该问题的分析 - 语言规范只是不允许在表达式上下文中使用大括号括起来的列表 - 对吗?
  2. 是否有一个根本原因,为什么这是不允许的,因为括号括起的表达式可以从参数的类型推导出它的类型operator+?我怀疑这与C++中的每个表达式都需要具有不依赖于上下文的明确定义的类型这一事实有关,如果这是正确的,我将非常感谢您的确认.