gpt4 book ai didi

c++ - 为什么 c++17 的 emplace() 函数没有引用资格?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:49:57 29 4
gpt4 key购买 nike

C++17 引入了一些新的函数签名 emplace_back()类型函数(std::optional<> 也有一个),但它们不是引用限定的。这允许 emplace_back()在临时对象上调用并绑定(bind)到左值引用,即使对象的生命周期没有延长。请考虑以下事项:

#include <vector>
#include <optional>
#include <iostream>

struct A {
A(int i) : i(i) { std::cout << "constructor called: " << i << '\n'; }
~A() { std::cout << "destructor called\n"; }

int i;
};

int main() {
auto & a = std::optional<A>().emplace(5);
std::cout << "a: " << a.i << '\n';
auto & v = std::vector<A>().emplace_back(5);
std::cout << "v: " << v.i << '\n';

// This fails to compile, because value() *is*
// ref-qualified so it cannot bind to an lvalue reference
//auto & a2 = std::optional<A>(std::in_place, 5).value();

auto const & a2 = std::optional<A>(std::in_place, 5).value();
std::cout << "a2: " << a2.i << '\n';
}

输出:

constructor called: 5
destructor called
a: 5
constructor called: 5
destructor called
v: 0
constructor called: 5
destructor called
a2: 5

我找不到与此相关的任何现有错误或问题,但也许我只是遗漏了一些东西。在std::optional<>::value()的情况下,它大部分都有效,但仍然允许绑定(bind)到 const 左值引用,同时不能适本地延长包含类型的生命周期。

这些函数没有引用限定的原因是什么,为什么 std::optional<>::value()在右值上使用时不能正确延长包含对象的生命周期?

最佳答案

std 库中几乎没有任何东西是引用限定的。

至于value,它返回一个右值引用。当您有一个右值限定方法返回对内部状态的引用时,您有两种选择。

您可以返回一个值,也可以返回一个右值引用。

如果您返回一个值,这意味着右值可选上的 .value() 会移动,而左值可选上的 .value() 不会。这可能令人惊讶。

.value() 返回右值的代价是引用生命周期延长不适用。 .value() 返回右值拷贝的代价是移动的代价,加上它表现不同的惊喜。

两者都有缺点。我记得它是可选设计中的一个讨论点。如果我的内存是正确的,那就意味着这个决定是睁着眼睛做出的。

除非对引用生命周期延长进行极端改进,否则将右值返回到内部状态的右值函数将始终绑定(bind)到 const& 而不会延长外部对象的生命周期。

我的经验中真正的痛点是for(:)循环;

std::optional<std::vector<int>> try_get_vec();

for (int x : try_get_vec().value()) // I know the optional won't be empty

上面有一个悬空引用。

关于c++ - 为什么 c++17 的 emplace() 函数没有引用资格?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54116810/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com