【问题标题】:When it make sense to replace "class_name obj_name = func()" by "class_name obj_name{func()}"?何时将“class_name obj_name = func()”替换为“class_name obj_name{func()}”有意义?
【发布时间】:2013-03-23 11:28:12
【问题描述】:

在代码中,我看到以下构造:

const class_name obj_name{func()};

func() 返回一个名为class_name 的类的对象。所以,我想知道为什么不使用以下结构:

const class_name obj_name = func();

【问题讨论】:

    标签: c++ assign initializer-list


    【解决方案1】:

    从 C++11 开始,引入了 uniform initialization 特性,它提供了多种初始化类型的方法。

    在这种情况下,两种语法都会调用class_name(class_name const&) 复制构造函数(如果存在的话)。因此没有真正的区别。这只是一个偏好问题。

    注意{} 语法在这种情况下并不总是表现得像这样:如果有适当类型的initialization_list构造函数,则使用该构造函数,否则类元素使用适当的构造函数进行初始化。

    Most Vexing Parse 原则(如果它可能被解释为函数原型,那么它会)发生的情况下,您需要使用两者之一来告诉编译器以下不是函数原型:

    typename class_name obj_name(func());
    class_name obj_name { func() };
    

    【讨论】:

      【解决方案2】:
      const class_name obj_name{func()};
      

      通过上面的写法,作者试图遵循统一初始化语法(由C++11引入),以避免vexing parse最令人头疼的解析,即使是经验丰富的程序员也会意外陷入其中。他正在尝试将最佳实践灌输到他的大脑中,这样他就不会偶尔陷入上述解析问题,如下所述。

      考虑一下,

      struct X { /*....*/ }; // some class
      
      struct Y 
      {
          Y();
          Y(int i);
          Y(X x);
      };
      

      现在可以这样写了:

      Y y(100); // declare an object y of type Y
      

      调用第二个构造函数,这很好。到目前为止,一切顺利!

      但不小心有人写了这个:

      Y y(); 
      

      (错误地)认为它调用了默认构造函数。但事实是它不会调用默认构造函数。相反,它声明了一个不带参数的函数y,并返回Y。这在 C++ 中称为恼人的解析

      同样,也可以这样写(不小心),

      Y y(X());
      

      认为它调用了第三个构造函数,传递了一个动态创建的X 类型的对象。再次,这是错误的。相反,它声明了一个函数y,它接受一个函数指针(函数类型,不接受任何内容并返回X)并返回Y。它在 C++ 中被称为最令人头疼的解析

      所以统一的初始化语法避免了所有这些问题,你可以这样写:

      Y y1{};      // invokes 1st constructor
      Y y2{100};   // invokes 2nd constructor
      Y y3{X{}};   // invokes 3rd constructor
      

      并遵循相同的语法,

      Y { function_call() }; 
      
      const class_name obj_name { func() }; // taken from your question!
      

      这是统一,当然也是最佳实践,不是吗?

      希望对您有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-08
        • 1970-01-01
        • 2011-10-31
        • 1970-01-01
        相关资源
        最近更新 更多