移动向量的最后一个元素

发布于 2025-01-30 04:48:28 字数 222 浏览 3 评论 0 原文

从向量获取最后一个(重)元素并将其删除并制作尽可能少的副本的最有效方法是什么? 是

template <typaname T>
T moveLastElement (std::vector<T>& vec) {
    T t = std::move(vec.back());
    vec.pop_back();
    return t;
}

What is the most efficient way to obtain the last (heavy) element from a vector and remove it, and make as few copies as possible?
Is it

template <typaname T>
T moveLastElement (std::vector<T>& vec) {
    T t = std::move(vec.back());
    vec.pop_back();
    return t;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

这样的小城市 2025-02-06 04:48:28

由于我们谈论的是复制Elision,特别是NVRO,因此我假设您正在编译(至少)C ++ 17,所以有一个有趣的边缘情况。

假设您具有这样的函数:

heavy_object fox_this_compiler ()
{
    heavy_object h1;
    heavy_object h2;

    return (some_condition_that_cant_be_evaluated_at_compile_time) ? h1 : h2;
}

现在编译器在Quandry中,因为它无法构造 h1 H2 < /代码>在呼叫站点上,这就是NVRO所依赖的。因此(而且我只是进行了快速测试),它返回副本(你们一个语言律师可以告诉我原因)。

因此,在这种情况下,从要返回的对象中明确移动是值得的,正如您在:

我不确定是否有某种类型的特征可以让您知道您是否需要在任何特定实例中执行此操作,但是如果有我不知道。


编辑:有一种方法。只需将呼叫呼叫 std ::移动如果您不需要它,GCC就会警告您(但是,如果您这样做,那将不会)。漂亮。但是,可悲的是,当您确实需要时,它不会警告您,并且您无法将其放入。

Since we're talking about copy elision, and specifically NVRO, and I'm assuming @presto that you're compiling for (at minimum) C++17, there's an interesting edge case.

Suppose you have a function like this:

heavy_object fox_this_compiler ()
{
    heavy_object h1;
    heavy_object h2;

    return (some_condition_that_cant_be_evaluated_at_compile_time) ? h1 : h2;
}

Now the compiler's in a quandry, because it can't construct both h1 and h2 at the call site, and that's what NVRO depends on. So (and I just ran a quick test), it returns a copy (and one of you language lawyers can tell me why).

So this is a case where explicitly moving from the object you're returning is worthwhile, as you can see in the:

Live demo

I'm not sure if there's some kind of type trait to let you know if you need to do this in any particular instance, but if there is I don't know about it.


Edit: turns out there is a way. Just stick the call to std::move in there and if you don't need it, gcc will warn you (but if you do, it won't). Nifty. But, sadly, it won't warn you when you do need it and you fail to put it in.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文