C++类声明中为何无法用括号形式调用构造函数初始化类成员?
语法限制的核心原因
- 根本原因是为了规避C++中经典的「最令人头疼的解析(Most Vexing Parse)」语法歧义。如果允许类内成员使用括号形式初始化,编译器将无法区分部分语句是成员变量初始化还是成员函数声明。
举个典型的歧义场景:
class Test { Foo bar(int()); // 语法歧义:到底是声明Foo类型成员bar,用临时int值初始化?还是声明成员函数bar,返回值为Foo,参数是返回int的无参函数指针? };
C标准委员会在设计C11的非静态数据成员初始化(NSDMI)特性时,为了从根源上避免这类歧义,直接限定类内成员默认初始化只能使用=赋值初始化或者花括号列表初始化两种形式,排除了括号初始化的语法。
替代方案
你可以直接使用花括号初始化达成完全相同的效果,该写法从C++11开始就完全合法:
class Bar { Foo foo{2}; // 编译正常,和你预期的括号初始化行为完全一致 int thisisok = 2; };
也可以使用=加显式构造调用的写法:
Foo foo = Foo(2);
未来是否会放开该限制
目前来看几乎没有可能。括号初始化的歧义是语法层面的原生问题,强行放开只会引入大量的兼容问题和难以排查的语法二义性bug,而现有的花括号、等号初始化两种方案已经完全覆盖了括号初始化的使用场景,不存在功能缺口,完全没有必要为了支持一种冗余的写法引入额外的复杂度。
内容的提问来源于stack exchange,提问作者Jabberwocky
相关产品推荐
相关产品推荐

