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

direct-initialization vs direct-list-initialization (C++)

本文关键字:初始化 C++ 列表      更新时间:2023-10-16

直接;VS;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"};

为了完整起见,我在这里提到它。我对此页面的实际问题在下一段中列出>>

 
直接国际化;VS;DIRECT-LIST初始化
答案显示,在直接初始化的类别中,可以区分直接初始化间接列表初始化

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++),所以请不要对我太苛刻;-)

nbsp
(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有一个初始值设定项列表构造函数,则对于brace-init-initifiers(列表初始化),它将始终优先于其他构造函数,在您的情况下为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容器具有这样的初始值设定项列表构造函数

  • 否则,重载解析开始生效,并返回到由重载解析过程选择的任何可用构造函数;

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


我们在这里涵盖了所有可能的初始化吗
来自我的有限的C++知识,我相信所有可能的初始化个对象(本机类型或用户定义类型的对象)具有已在上面的示例中涵盖。这是正确的吗?我忽略了吗某物

没有。你没有。不包括引用初始化,在C++中有五种方法可以初始化对象。

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

您可以在这里找到更多信息

列出参数求值从左到右的初始化保证。在这个例子中,我们将从istream数据创建std::tuple,然后输出元组的例子可以在这里找到:

#include <iostream>
#include <sstream>
#include <tuple>
template<typename T, typename CharT>
T extract(std::basic_istream<CharT>& is) {
T val;
is >> val;
return val;
}
void print(const std::tuple<int, long, double>& t) {
using std::cout;
cout << std::get<0>(t) << " " << std::get<1>(t) << " " << std::get<2>(t) << std::endl;
}
int main()
{
std::stringstream ss1;
std::stringstream ss2;
ss1 << 1 << " " << 2 << " " << 3;
ss2 << 1 << " " << 2 << " " << 3;
auto compilerOrder    = std::tuple<int, long, double>( extract<int>(ss1), extract<long>(ss1), extract<double>(ss1) );
auto leftToRightOrder = std::tuple<int, long, double>{ extract<int>(ss2), extract<long>(ss2), extract<double>(ss2) };
print(compilerOrder);
print(leftToRightOrder);
}

输出:

3 2 1
1 2 3

正如您所看到的,当我们在函数括号内多次使用相同的类流资源时,差异就会显现出来。

还有我关于的问题