我正在使用一组自定义C ++库,它们提供表示序列的类型。有一个重载operator+
,它接收两个序列并连接它们,一个初始化器接受一个std::intializer_list
,可以用来用值列表初始化序列。这些功能中的每一个都可以很好地运行,但由于某些原因,它们不能很好地协同工作。
这是reduced test case that shows off the issue:
#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 };
无法编译,并报告有关缺少的primary-expression的错误。这让我相信语言语法不允许这样的事情。
我的问题如下:
operator+
的参数类型推导出来?我怀疑这与C ++中的每个表达都需要具有不依赖于上下文的明确定义的类型这一事实有关,如果这是正确的我会感激确认