C++17 和 emplace_back(...) 中保证复制省略

Nil*_*ils 6 c++ c++17

emplace_back(...)是在 C++11 中引入的,以防止创建临时对象。现在,使用 C++17 纯左值更加纯粹,因此它们不再导致临时值的创建(有关更多信息,请参阅此问题)。现在我仍然不完全理解这些改变的后果,我们是否还需要emplace_back(...)或者我们可以回去push_back(...)再使用吗?

mar*_*inj 1

您可能会在这里看到:std::vector::push_back该方法需要 CopyInsertable 或 MoveInsertable,也需要const T& valueor T&& value,所以我不知道省略在这里如何使用。

强制复制省略的新规则在以下示例中使用:

struct Data {
    Data() {}
    Data(const Data&) = delete;
    Data(Data&&) = delete;
};

Data create() {
    return Data{};  // error before c++17   
}

void foo(Data) {}

int main()
{
    Data pf = create();
    foo(Data{});  // error before c++17
}
Run Code Online (Sandbox Code Playgroud)

因此,您有一个不支持复制/移动操作的类。为什么,因为也许它太贵了。上面的例子是一种始终有效的工厂方法。使用新规则,您无需担心编译器是否实际上会使用省略 - 即使您的类支持复制/移动。

我不认为新规则会让push_back更快。emplace_back 仍然更高效,但不是因为复制省略,而是因为它就地创建对象并向其转发参数。