[英]Does gcc have a extension overload for std::vector::emplace_back?
[英]Can I reliably emplace_back in a vector of a type that does not have an assignment operator?
我在 GCC、Clang 和 MSVC 中进行了一些测试,发现emplace_back
从不在包含的类上调用赋值运算符。 它只在重新分配发生时调用复制或移动构造函数。 标准是否以某种方式保证了这种行为?
用例是我有一些类按顺序存储在一个数字中,这个数字只会随着时间的推移而增长,直到整个向量被破坏。 我很乐意从赋值运算符中清除我的代码。
这些要求记录在 cppreference.com 上。
对于std::vector<T>::emplace_back
:
类型要求
-
T
(容器的element
类型)必须满足MoveInsertable
和EmplaceConstructible
的要求。
此外, std::vector
有一个一般要求,即类型必须是Erasable
。
EmplaceConstructible要求类型可以使用给定的分配器构造,并提供参数。 由于您使用的是默认分配器std::allocator<T>
,这仅意味着该类型具有带有这些参数的可访问构造函数。
MoveInsertable要求该类型可使用给定的分配器构造,使用类型T
的右值。 对于std::allocator
这意味着该类型具有可访问的移动构造函数。
Erasable要求该类型可以使用给定的分配器进行破坏。 对于std::allocator
这意味着它有一个可访问的析构函数。
就是这样(除了关于完整类型与不完整类型的一些规则)。 没有提及赋值运算符的要求。
但在 C++11 之前,过去类型总是必须是CopyAssignable
和CopyConstructible
。 这已经放松了。 现在,除了Erasable
之外,要求仅取决于对向量执行的操作。
是的,如果移动构造函数可用(或就地构造),回放将调用移动构造函数:
#include <iostream>
#include <vector>
struct Pt {
Pt() = default;
Pt& operator=(Pt const& other) = delete;
Pt(Pt const&) { std::cout << "copy ctor" << std::endl; }
Pt(Pt&&){ std::cout << "move ctor" << std::endl; }
};
int main(int argc, char *argv[])
{
std::vector<Pt> v;
v.emplace_back(Pt{});
return 0;
}
这是cppreference对emplace_back
的评价:
T
(容器的元素类型)必须满足MoveInsertable和EmplaceConstructible的要求。
对于EmplaceConstructible ,要求是std::allocator_traits<A>::construct(m, p, args);
有效。 这是无聊的约束,只对实际放置元素有用。
MoveInsertable似乎是重新分配所需的概念。
对于MoveInsertable ,要求是std::allocator_traits<A>::construct(m, p, rv);
有效,其中rv
是T
类型(即您的类型)的右值表达式。
construct
的定义有点令人困惑,但对于大多数意图和目的而言,它似乎只是将参数转发给构造函数。
换句话说,这两个概念似乎证实了对emplace_back
的唯一约束是您需要提供:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.