DIRECT-VS COPY-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 ++),所以请不要对我太苛刻; - )
答案 0 :(得分:7)
(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,则始终优先于 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容器具有初始化列表构造函数。
否则,Overload resolution会启动,它会回退到重载解析过程选择的任何可用构造函数;
否则,如果该类没有用户定义的构造函数且它是聚合类型,则会直接初始化类成员。
我们是否覆盖了所有可能的初始化?
来自我的 关于C ++的知识有限,我相信所有可能的初始化 对象(本机类型或用户定义类型对象)具有 已在上面的例子中介绍过。那是对的吗?我忽略了吗 什么?
不。你没有。排除引用初始化,有五种方法可以在C ++中初始化对象。
您可以找到更多信息here
答案 1 :(得分:3)
列表初始化保证参数评估的从左到右的顺序。在此示例中,我们将从Carbon::setWeekendDays([Carbon::SUNDAY]);
数据创建std::tuple
,然后输出元组example can be found here:
istream
输出:
#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);
}
正如您所看到的,差异将被看到然后我们在函数括号内使用多次相同的类似流的资源。