我正在尝试为std::initializer_list
重载运算符,但是以下代码无法在GCC 4.7.2和Clang 3.2中编译:
#include <initializer_list>
void operator+(const std::initializer_list<int>&, const std::initializer_list<int>&);
int main() {
{1, 2} + {3, 4};
}
13.5/6规定:运算符函数至少应当有一个参数,其类型为类、枚举或者是指向它们的引用。标准将initializer_list
定义为模板类,所以我认为这个代码应该符合规范。然而,显然Clang和GCC都认为我正在尝试使用它们非标准的块表达式。
GCC:
Compilation finished with errors:
source.cpp: In function 'int main()':
source.cpp:7:8: warning: left operand of comma operator has no effect [-Wunused-value]
source.cpp:7:9: error: expected ';' before '}' token
source.cpp:7:9: warning: right operand of comma operator has no effect [-Wunused-value]
source.cpp:7:13: error: expected primary-expression before '{' token
source.cpp:7:13: error: expected ';' before '{' token
Clang:
Compilation finished with errors:
source.cpp:7:5: warning: expression result unused [-Wunused-value]
{1, 2} + {3, 4};
^
source.cpp:7:9: error: expected ';' after expression
{1, 2} + {3, 4};
^
;
source.cpp:7:8: warning: expression result unused [-Wunused-value]
{1, 2} + {3, 4};
^
source.cpp:7:13: error: expected expression
{1, 2} + {3, 4};
^
2 warnings and 2 errors generated.
这段代码是否可以编译?如果不能,为什么?
编辑:
并且毫不意外的是,VS 2012的十一月版CTP也失败了:
error C2143: syntax error : missing ';' before '}'
error C2059: syntax error : '{'
error C2143: syntax error : missing ';' before '{'
std::initializer_list<int>({1,2}) + std::initializer_list<int>({2,1})
了吗?花括号列表本身不是初始化列表,只能在某些情况下(例如auto
推导)用于定义一个初始化列表。 - Kerrek SBstd::initializer_list
?我猜这就是问题的关键。 - Seth Carnegieauto x = {1, 2, 3};
时,x
的类型是std::initializer_list<int>
。但这些规则在8.5中是单独规定的;否则,花括号列表不像标识符和字面量那样是一等实体。 - Kerrek SBoperator+({1,2}, {2,1})
,但这仅适用于当前代码,例如template <typename T> void operator+(T, T)
就无法使用。 - Kerrek SBstd::initializer_list
有点像说整数字面量不同于int
。但语法期望的是赋值表达式,而不是初始化器子句,后者包括赋值表达式和带大括号初始化列表。 - Potatoswatter