C ++中的语义差异,定义了一个常量数据实例

时间:2015-02-06 05:59:46

标签: c++ c++11 syntax

在初始化常量数据成员时,以下四种不同的语法是否做同样的事情,例如在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识别为有效语句?

4 个答案:

答案 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};

那不会编译。你可以通过老式初始化来实现,但不能统一初始化。