转发就地构建和列表初始化 [英] Forwarded in-place construction and list-initialization

查看:106
本文介绍了转发就地构建和列表初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过转发就地构造,我的意思是 std :: allocator: :construct 和各种emplace方法,例如 std :: vector: :emplace_back .我只是发现在C ++中转发的就地构造不能(无法?)利用列表初始化语法.结果,似乎永远无法转发就位构造聚合.我只想确保转发的就地构造是否不支持列表初始化,因此不支持聚合类型.这是由于语言的限制吗?有人可以提供有关此问题的标准的参考吗?以下是说明:

By forwarded in-place construction, I take to mean std::allocator::construct and the various emplace methods, e.g., std::vector::emplace_back. I just find that forwarded in-place construction in C++ does not (unable to?) take advantage of the list-initialization syntax. As a result, it seems one can never forward in-place construct an aggregate. I just want to make sure whether forwarded in-place construction does not support list-initialization and hence aggregate types. Is this due to the limitation of the language? Could someone provide reference to the standard concerning this issue? Following is an illustration:

虽然我们可以像直接进行现场施工

While we can do in-place construction directly like

int(*p)[3] = ...;
new(p) int[3]{1, 2, 3};

我们不能像这样进行转发的就地构建

we cannot do forwarded in-place construction like

std::allocator<int[3]> allo;
allo.construct(p, 1, 2, 3);

推荐答案

虽然{}被称为统一初始化语法,但远非通用.

While {} has been called uniform initialization syntax, it is far from universal.

举两个例子:

size_t a = 3;
size_t b = 1;
std::vector<size_t> v1{a,b};
std::vector<size_t> v2(a,b);

在第一种情况下,我们构造一个包含两个元素31的向量.

in the first case, we construct a vector containing two elements, 3 and 1.

在第二种情况下,我们创建一个包含1,1,1的矢量-3个1副本.

In the second case, we create a vector containing 1,1,1 -- 3 copies of 1.

在线示例.

因此,在某些情况下,基于{}的构造可能会导致与基于()的构造不同的行为.而且,在上述情况下,无法使用{}构造(我知道)来达到"1的3个副本"语法.但是{3,2}情况可以通过简单地显式创建一个初始化程序列表并将其传递给()来处理.

So {} based construction can cause a different behavior than () based construction in some cases. What more, in the above case, there is no way to reach the "3 copies of 1" syntax using {} construction (that I know of). But the {3,2} case can be handled by simply explicitly creating an initializer list and passing it to ().

由于大多数带有初始化程序列表的类型都可以通过显式传递一个初始化程序列表来构造,而C ++标准库是为具有构造函数的类型而不是没有构造函数的类型而设计的,因此C ++标准库几乎使用,而不是{}.

As most types that take initializer lists can be emplace constructed by explicitly passing in an initializer list, and the C++ standard library was designed for types with constructors more than types without them, the C++ standard library nearly uniformly emplace constructs using () and not {}.

缺点是无法通过此机制放置要进行列表初始化的类型.

The downside is that types that want to be list-initialized cannot be emplaced via this mechanism.

从理论上讲,可以将使用{}构造的list_emplace方法添加到每个接口中.我鼓励您提出这一建议!

In theory, list_emplace methods that construct using {} instead could be added to each interface. I encourage you to propose that!

这篇关于转发就地构建和列表初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆