直接初始化与直接列表初始化(C++)
direct-initialization vs direct-list-initialization (C++)
直接;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
正如您所看到的,当我们在函数括号内多次使用相同的类流资源时,差异就会显现出来。
还有我关于的问题
- 是否可以初始化不可复制类型的成员变量(或基类)
- C++使用整数的压缩数组初始化对象
- C++初始化基类
- 多成员Constexpr结构初始化
- 复制列表初始化的隐式转换的等级是多少
- 内联映射初始化的动态atexit析构函数崩溃
- 如何在C++中初始化嵌套类中的2个memeber
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 没有用于初始化C++中的变量模板的匹配构造函数
- 在未初始化映射的情况下,将值插入到映射的映射中
- C++成员初始化
- 为什么在C++中首先初始化成员类
- 同时具有"聚合初始化"和"模板推导"
- 初始化具有非默认构造函数的std::数组项的更好方法
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 在C和C++中初始化结构中的数组
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 在函数内部的声明中初始化数组,并在外部使用它
- 继承:构造函数,初始化C++11中基类的类C数组成员