首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >std::get不转发std::apply的rvalue引用

std::get不转发std::apply的rvalue引用
EN

Stack Overflow用户
提问于 2020-01-03 21:04:07
回答 1查看 104关注 0票数 0

我想知道为什么当使用元组中的引用类型时,std::apply不转发rvalue-reference (参见Live):

代码语言:javascript
复制
#include <type_traits>
#include <tuple>

template<typename T>
void assertRvalueReference(T&& t)
{   
    static_assert(std::is_rvalue_reference_v<decltype(t)>, "Ups"); 
}

int main()
{
    struct A{};
    A a;
    int v;
    auto t = std::tuple<A&&, int>(std::move(a), v); // essentially `std::forward_as_tuple(v, std::move(a))`

    std::apply([](auto&& arg, ...)
               {
                   assertRvalueReference(std::forward<decltype(arg)>(arg)); 
               }, std::move(t));

    std::apply([](auto&& arg, ...)
               {
                   // assertRvalueReference(arg); // This should in my opinion not fail
               }, t);

    assertRvalueReference(non_std_get<0>(t)); 
}

造成这种情况的根本原因是std::get和引用折叠规则。如果std::apply在内部使用这个non_std_get,不是更有意义吗

代码语言:javascript
复制
template<std::size_t Index, typename Tuple>
constexpr decltype(auto) non_std_get(Tuple&& t)
{
    using Type = std::tuple_element_t<Index, std::remove_cvref_t<Tuple>>;
    if constexpr(std::is_rvalue_reference_v<Type>)
    {
        return std::move(std::get<Index>(t));
    }
    else
    {
        return std::get<Index>(t);
    }
}

这将导致一个完美的转发

代码语言:javascript
复制
std::apply([](auto&& arg){/*arg is here `int&&`*/}, t);
EN

回答 1

Stack Overflow用户

发布于 2020-01-03 21:38:04

问题不在于std::apply,而在于您的lambda。

在您的lambda中,arg总是一个左值。您需要使用std::forward将其显式转换为右值,才能使其成为右值。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59579132

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档