C++中X()与X{}两种初始化语法的区别是什么?
C++ 中
X()与X{}初始化语法差异及相关问题解答 1. 基础概念说明
X()和X{}都属于C++合法的初始化方式:
X{}是C++11引入的*列表初始化(又称统一初始化)*语法,默认场景下执行默认初始化X()是C++98就存在的值初始化语法,同样是合法的初始化手段
2. int value();不符合预期的原因
这是C经典的语法解析歧义规则导致的:C标准规定,任何可以被解析为函数声明的语句,都会被编译器优先判定为函数声明。
你写的int value();会被识别为「声明一个名为value、返回值为int、无入参的函数」,而非你预期的「定义一个int类型的变量value并初始化」,所以后续如果你把它当变量赋值、访问都会触发编译错误。
3. 示例代码逐行解释
你提供的测试代码中,类X是重载了()运算符的仿函数类,main函数中各语句逻辑如下:
class X{ public: void operator()(string str) { cout << "calling functor x with parameter" << str << endl; } }; int main() { X foo; // 默认初始化X类对象foo,调用默认构造函数 // foo("hi"); // 调用foo的重载()运算符,传入"hi" X()("hi"); // 先通过X()创建一个临时的X类对象,再直接调用这个临时对象的重载()运算符,传入"hi",执行完成后临时对象自动销毁 X c = X{}; // 用列表初始化创建X类临时对象,再拷贝/移动初始化对象c,C++17后会被优化为原地初始化,等价于X c{} X a = X(); // 用值初始化创建X类临时对象,再拷贝/移动初始化对象a,C++17后优化为原地初始化 int value{}; // 列表初始化int变量,值被初始化为0 // int value(); // 被解析为返回int、无入参的函数value的声明,不符合变量定义的预期 }
4. X()与X{}的核心差异
- 语法歧义性不同:
X{}不存在函数声明歧义,比如X a{};一定是声明变量并初始化;但X a();会被解析为函数声明,无法达到定义变量的目的 - 窄化转换限制不同:列表初始化禁止隐式窄化转换,比如
int a{3.14};会直接编译报错,而int a(3.14);只会触发警告,隐式把浮点数截断为整数3 - 构造函数匹配优先级不同:如果类定义了接收
std::initializer_list参数的构造函数,X{}会优先匹配这个初始化列表构造函数,而X()会优先匹配普通无参构造函数 - 内置类型初始化效果差异:对于内置类型(比如int、char等),
int a{};一定会被值初始化为0;int a();是函数声明;int a = int();会被初始化为0;而局部作用域下的int a;默认初始化会是未定义的垃圾值
内容的提问来源于stack exchange,提问作者milaimac
相关产品推荐
相关产品推荐

