繁体   English   中英

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

[英]direct-initialization vs direct-list-initialization (C++)

直接 - 复制 - 初始化
通过这个问题( 它是直接初始化还是复制初始化? )我学到了直接初始化复制初始化之间的区别:

 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有一个初始化列表构造函数 ,它将始终优于其他其他构造函数的brace-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容器都有这样的初始化列表构造函数

  • 否则, 重载决策启动并且它会回退到由重载解析过程选择的任何可用构造函数;

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


我们在这里涵盖了所有可能的初始化吗?
根据我对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

正如您所看到的,差异将被看到然后我们在函数括号内使用多次相同的类似流的资源。

还有我的问题

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM