直接初始化与直接列表初始化(C++)

2022-02-25 00:00:00 c++ c++17 list-initialization

直接- ;与 ;复制初始化
通过这个问题(Is it direct-initialization or copy-initialization?)我了解了直接初始化和复制初始化的区别:

direct-initialization                   copy-initialization
-----------------------                 ---------------------

obj s("value");                         obj s = obj("value");
                                        obj s = "value";

obj s{"value"};                         obj s = {"value"};
                                        obj s = obj{"value"};
为了完整起见,我在此提及它。我对此页面的实际问题列在下一段中>>

 ;
直接初始化 ;与 ;直接列表初始化
答案显示,在直接初始化类别中,可以区分直接初始化和直接列表初始化。:

obj s("value");   // direct-initialization

obj s{"value"};   // direct-list-initialization

我知道列表初始化不允许缩小范围,因此像int x{3.5};这样的初始化不会编译。但除此之外,我还有几个问题:

 ;
(1)

在编译器输出上有什么不同 obj s("value");obj s{"value"};
让我们考虑一个没有任何优化的编译器。我想知道任何可能的技术差异:-)

 ;
(2)对于多变量初始化,也许我应该问完全相同的问题,比如:
obj s("val1", "val2");obj s{"val1", "val2"};

 ;
(3)我注意到列表初始化有时会调用不同的构造函数,如:

vector<int> a{10,20};   //Curly braces -> fills the vector with the arguments
vector<int> b(10,20);   //Parentesis -> uses arguments to parameterize some functionality

这怎么可能?  ;
 ;

我们是否在此涵盖了所有可能的初始化?
根据我有限的C++知识,我相信所有可能的对象初始化(无论是本机类型的还是用户定义的类型的对象)都已经在上面的示例中涵盖了。对吗?我是不是忽略了什么?  ;
 ;


PS:我正在学习C++(我知道C,但还不会C++),所以请不要对我太苛刻;-)


解决方案

 ;
(1)

在编译器输出方面有什么不同 obj s("value");obj s{"value"};?让我们考虑一下编译器 在没有任何优化的情况下。我想知道任何可能的技术问题 差异:-)

 ;
(2)也许我应该问一个完全相同的问题 多变量初始化,如:
obj s("val1", "val2");obj s{"val1", "val2"};

 ;
(3)我注意到列表初始化可以 有时调用不同的构造函数,如:

vector<int> a{10,20};   //Curly braces -> fills the vector with the arguments
vector<int> b(10,20);   //Parentesis -> uses arguments to parameterize some functionality

这怎么可能?

  • 如果类类型obj有initializer-list constructor,则对于括号-init-initializers(列出初始化),它将始终优先于其他构造函数,在您的情况下obj s{"value"};

    这意味着如果您有一个以std::initializer_list<T>作为第一个参数的构造函数,并且其他参数都是默认值,那么它是首选的。示例

    struct A{
        A(std::initializer_list<std::string>);    //Always be preferred for A a{"value"}
        A(std::string);
    };
    

    std::vector<T>和其他STL容器都有这样的初始值设定项列表构造函数。

  • 否则,Overload resolution生效,它将回退到重载解决过程选择的任何可用构造函数;

  • 否则,如果该类没有用户定义的构造函数,并且它是聚合类型,它将直接初始化类成员。


我们是否在此介绍了所有可能的初始化?
来自我的 由于对C++的了解有限,我相信所有可能的初始化 的对象(本机类型或用户定义类型的对象)具有 已经在上面的示例中进行了介绍。对吗?我是不是忽略了 有什么事吗?

没有。您没有。除了引用初始化之外,在C++中有五种方式可以初始化对象。

  • 直接初始化
  • 列表初始化
  • 复制初始化
  • 值初始化
  • 聚合初始化(仅适用于聚合类型)

您可以找到更多信息here

相关文章