如何在 C++14 中保留左值引用的同时衰减右值引用类型?
How to decay rvalues reference type whilst preserving lvalue references in C++14?
我有以下 C++14 lambda
#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
有开箱即用的东西吗?
您可以将类型特征写为
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
您可以将 std::is_rvalue_reference
与 std::conditional
一起使用,两者均来自 <type_traits>
header。
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));
};
扩展 您可以将条件类型封装在与 C++14 兼容的别名中,如下所示:
#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));
};
我有以下 C++14 lambda
#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
有开箱即用的东西吗?
您可以将类型特征写为
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
您可以将 std::is_rvalue_reference
与 std::conditional
一起使用,两者均来自 <type_traits>
header。
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));
};
扩展
#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));
};