In-class 使用构造函数的成员初始值设定项:允许吗?
In-class member initializer using a constructor: is it allowed?
我最近在 Danny Kalev 的文章 Get to Know the New C++11 Initialization Forms 中发现了一段有趣的代码:
class C
{
string s("abc");
double d=0;
char * p {nullptr};
int y[5] {1,2,3,4};
public:
C();
};
string s("abc");
行对我来说似乎很可疑。我认为在-class 中初始化成员时不允许使用构造函数。
并且此代码(简化为 class C { string s("abc");
};`)无法使用
进行编译
- clang 3.6.1(编译器参数为
-std=c++11 -Wall -Wextra -Werror -pedantic-errors
)
- g++ 5.1.0(编译器参数相同:
-std=c++11 -Wall -Wextra -Werror -pedantic-errors
)
- vc++ 18.00.21005.1(编译器参数为
/EHsc /Wall /wd4514 /wd4710 /wd4820 /WX /Za
)
- vc++ 19.00.22929.0(编译器参数由服务预定义:
/EHsc /nologo /W4 /c
)
我说的对吗,这篇文章有错误吗?
Am I right and there is an error in this article?
是的,是文章中的错误。
在数据成员的声明中只允许 大括号或等式初始化器。 d
、p
、y
的初始化是正确的,但s
不正确。这样做的理由是,使用 表达式列表 会使声明与函数声明产生歧义,并且还会导致与 class 主体中的名称查找发生冲突。
An example from Bjarne Stroustrup:
class A {
public:
A() {}
A(int a_val) : a(a_val) {}
A(D d) : b(g(d)) {}
int a = 7;
int b = 5;
private:
HashingFunction hash_algorithm{"MD5"}; // Cryptographic hash to be applied to all A instances
std::string s{"Constructor run"}; // String indicating state in object lifecycle
};
我最近在 Danny Kalev 的文章 Get to Know the New C++11 Initialization Forms 中发现了一段有趣的代码:
class C
{
string s("abc");
double d=0;
char * p {nullptr};
int y[5] {1,2,3,4};
public:
C();
};
string s("abc");
行对我来说似乎很可疑。我认为在-class 中初始化成员时不允许使用构造函数。
并且此代码(简化为 class C { string s("abc");
};`)无法使用
- clang 3.6.1(编译器参数为
-std=c++11 -Wall -Wextra -Werror -pedantic-errors
) - g++ 5.1.0(编译器参数相同:
-std=c++11 -Wall -Wextra -Werror -pedantic-errors
) - vc++ 18.00.21005.1(编译器参数为
/EHsc /Wall /wd4514 /wd4710 /wd4820 /WX /Za
) - vc++ 19.00.22929.0(编译器参数由服务预定义:
/EHsc /nologo /W4 /c
)
我说的对吗,这篇文章有错误吗?
Am I right and there is an error in this article?
是的,是文章中的错误。
在数据成员的声明中只允许 大括号或等式初始化器。 d
、p
、y
的初始化是正确的,但s
不正确。这样做的理由是,使用 表达式列表 会使声明与函数声明产生歧义,并且还会导致与 class 主体中的名称查找发生冲突。
An example from Bjarne Stroustrup:
class A {
public:
A() {}
A(int a_val) : a(a_val) {}
A(D d) : b(g(d)) {}
int a = 7;
int b = 5;
private:
HashingFunction hash_algorithm{"MD5"}; // Cryptographic hash to be applied to all A instances
std::string s{"Constructor run"}; // String indicating state in object lifecycle
};