在初始化常量数据成员时,以下四种不同的语法是否做同样的事情,例如在C ++ 11中是int类型?如果没有,有什么区别?
{
const int a = 5; //usual initialization, "=" is not assignment operator here it is an initialization operator.
}
{
const int a(5); //calling the constructor function directly
}
{
const int a = {5}; //similar to initializing an array
}
{
const int a{5}; //it should work, but visual studio does not recognizing it
}
为什么第四个不能被Visual Studio识别为有效语句?
答案 0 :(得分:7)
它们在Visual Studio 2013中都是有效且相同的(最后一个在VS2012中无效,如@remyabel建议的那样)。
两种{...}
语法可能与为类型调用的构造函数中的其他语法不同,但类型int
不使用构造函数。
在构建接受std::initializer_list<T>
的类时,它们会不同。
例如,这个构造函数以某种形式 - 始终是std::vector
的一部分
explicit vector( size_type count ... );
这是在C ++ 11中添加的
vector( std::initializer_list<T> init, const Allocator& alloc = Allocator() );
在这里,vector<int>(5)
将调用第一个构造函数并使矢量大小为5。
vector<int>{5}
将调用第二个并生成单个5
的向量。
答案 1 :(得分:4)
在C ++ 03中,这些是等价的
const int a = 3;
const int a(3);
在C ++ 11中,引入了统一初始化语法,因此
const int a{3};
const int a = {3};
是允许的并且是等效的。但是,前两个和后两个在所有情况下都不相同。 {}
不允许缩小范围。例如
int abc = {12.3f};
int xyz(12.3f);
以下是GCC所说的
错误:类型'float'不能缩小为'int' 初始化列表[-Wc ++ 11-narrowing]
int abc = {12.3f}; ^~~~~
警告:从'float'隐式转换为'int' 将值从12.3更改为12 [-Wliteral-conversion]
int abc = {12.3f}; ~^~~~~
所以前者产生错误,而后者只是一个警告。
统一初始化语法中的 警告:如果a
是接受std::initializer_list
的类型的对象,那么const MyClass a = { 1 }
将意味着您正在使用该构造函数即使它是可用的,也不是单个int
的构造函数(在Drew的anwer中解释);如果要选择其他构造函数,则必须使用()
语法。如果a
是一个数组,那么您正在使用聚合初始化。
See here用于C ++中可用的各种初始化选项。
答案 2 :(得分:1)
Visual Studio 2012不支持此语法。然而,它在VS2013中实现。 VS2012选项卡中initializers的文档没有描述使用大括号直接初始化的任何方式(aka,direct-list-initialization
)。以下是MSVC关于有效初始化程序语法的文档,从语言律师的角度来看,它并不一定反映出有效的内容。
声明者可以指定对象的初始值。唯一的方法 为const类型的对象指定一个值在声明符中。该 指定此初始值的声明符的一部分称为 初始化。有两种基本类型的初始化器:
- 使用等号语法调用初始值设定项,包括聚合初始值设定项:
= expression = { expression-list } = { { expression-list}, {expression-list}, . . . }
- 使用函数式语法调用初始化程序:
( expression )
答案 3 :(得分:0)
编码风格最终是主观的,并且极不可能从中获得实质性的性能优势。但是,我会说你从自由使用统一初始化中获得了什么:
所有4个陈述都有效且相同。
const int a = 5;
- &gt;无论如何,是正常的初始化语法。
无需解释。!
const int a(5);
- &gt;函数类型初始化
const int a = {5};
- &gt;数组类型初始化
const int a{5};
- &gt;它在Visual Studio 2012中是不允许的,但是,在Visual Studio 2013中添加了初始化列表支持。因此const int a {5}可以很好地编译VS2013中的任何问题。
但是,
你放弃的唯一真正的力量正在缩小。您不能使用较大的值初始化较小的值,并使用统一初始化。
int val{5.5};
那不会编译。你可以通过老式初始化来实现,但不能统一初始化。