"expected primary-expression before ‘{’ token" 使用自定义数据类型调用重载“<<”时
"expected primary-expression before ‘{’ token" when calling overloaded "<<" with customized data type
我有一个简单的 class 'A',内容如下:
class A {
public:
struct data_t {
int32_t val;
data_t(int32_t _val) :
val(_val) {
;
};
};
A& operator << (const data_t &data) {
printf("[%s] %d\n", __func__, data.val);
return *this;
};
void func(const data_t &data) {
printf("[%s] %d\n", __func__, data.val);
}
};
我尝试了以下代码并得到:
A a;
a<<{100}; //"expected primary-expression before ‘{’ token"
a<<A::data_t{100}; //OK.
a.func({100}); //OK.
为什么 <<{100};是 NG 并且 a.func({100});可以吗?
我不想用第二句,因为它太长太复杂了。
因为 A::data_t
有一个 转换构造函数 (一个非显式单参数构造函数)编译器可以进行从 int32_t
到 A::data_t
.
这意味着您可以简单地做例如
a << 100;
Why a<<{100}; is NG and a.func({100}); is OK?
该语言的语法只允许在某些地方使用大括号初始化列表。作为表达式中(算术)运算符的操作数,它通常是不允许的,即使有人认为对于重载运算符来说可能能够理解它。
可能允许使用大括号初始化列表:
- 在变量的初始值设定项中,class 成员,
new
表达式,默认参数(用于函数参数和非类型模板参数)
- 在类型说明符之后(功能类型转换符号)
- 作为函数调用和模板参数中的参数
- 作为赋值的右侧
- 作为
return
、co_return
和 co_yield
的操作数
- 作为范围内的初始值设定项-
for
假设我没有忘记任何情况,它们不能用于其他任何地方。
我有一个简单的 class 'A',内容如下:
class A {
public:
struct data_t {
int32_t val;
data_t(int32_t _val) :
val(_val) {
;
};
};
A& operator << (const data_t &data) {
printf("[%s] %d\n", __func__, data.val);
return *this;
};
void func(const data_t &data) {
printf("[%s] %d\n", __func__, data.val);
}
};
我尝试了以下代码并得到:
A a;
a<<{100}; //"expected primary-expression before ‘{’ token"
a<<A::data_t{100}; //OK.
a.func({100}); //OK.
为什么 <<{100};是 NG 并且 a.func({100});可以吗?
我不想用第二句,因为它太长太复杂了。
因为 A::data_t
有一个 转换构造函数 (一个非显式单参数构造函数)编译器可以进行从 int32_t
到 A::data_t
.
这意味着您可以简单地做例如
a << 100;
Why a<<{100}; is NG and a.func({100}); is OK?
该语言的语法只允许在某些地方使用大括号初始化列表。作为表达式中(算术)运算符的操作数,它通常是不允许的,即使有人认为对于重载运算符来说可能能够理解它。
可能允许使用大括号初始化列表:
- 在变量的初始值设定项中,class 成员,
new
表达式,默认参数(用于函数参数和非类型模板参数) - 在类型说明符之后(功能类型转换符号)
- 作为函数调用和模板参数中的参数
- 作为赋值的右侧
- 作为
return
、co_return
和co_yield
的操作数
- 作为范围内的初始值设定项-
for
假设我没有忘记任何情况,它们不能用于其他任何地方。