2

我有以下 C++14 lambda

https://godbolt.org/z/aexxTY

#include <boost/optional.hpp>


int main(){
    auto foo = [](auto && t) 
    {
        using T = decltype(t);
        return boost::optional<T>(std::forward<T>(t));
    };

    // This is fine because i is lvalue
    auto i = 10;
    foo(i);

    // This fails because i is rvalue
    foo(10);
}

首先注意 boost::optional 可以包含左值引用,但不能包含右值引用。

是否可以使用上述通用 lambda 将右值作为副本处理。我想要的是聪明的东西

using T = std::decay_if_rvalue<decltype(t)>::type

有开箱即用的东西吗?

4

3 回答 3

2

您可以将类型特征编写为

template< class T > struct remove_rvalue_reference       {typedef T type;};
template< class T > struct remove_rvalue_reference <T&&> {typedef T type;};

然后

using T = typename remove_rvalue_reference<decltype(t)>::type;

然后

auto i = 10;
foo(i);   // T will be int& in the lambda

foo(10);  // T will be int  in the lambda
于 2021-02-09T06:55:28.900 回答
2

您可以从标题中std::is_rvalue_reference与 , 一起使用。std::conditional<type_traits>

auto foo = [](auto && t) 
{
    using Orig = decltype(t);
    using T = std::conditional_t<std::is_rvalue_reference<Orig>::value,
            std::decay_t<Orig>, Orig>;
    return boost::optional<T>(std::forward<T>(t));
};

https://godbolt.org/z/WdTdco

于 2021-02-09T06:55:30.873 回答
1

Expanding on lubgr's answer you can encapsulate the conditional type in an alias compatible with C++14 like this:

#include <type_traits>

template <class T>
using decay_rvalue_reference_t = std::conditional_t<
    std::is_rvalue_reference<T>::value,
    std::decay_t<T>::type,
    T>;

auto foo = [](auto && t) 
{
    using T = decay_rvalue_reference_t<decltype(t)>;
    return boost::optional<T>(std::forward<T>(t));
};

https://godbolt.org/z/YW88Yf

于 2021-02-09T07:10:36.723 回答