add_rvalue_reference的实现

问题描述 投票:0回答:1

为什么当直接从函数返回类型推导出函数类型时,结果会变成右值引用,而

bool_constant
中的实现会产生正确的类型?

#include <type_traits>

using namespace std;

template <typename T>
T &&test_rvalue_reference(int);
template <typename T>
T test_rvalue_reference(...);

static_assert(is_same_v<decltype(test_rvalue_reference<void ()>(0)), add_rvalue_reference_t<void ()>>);     // error
static_assert(is_same_v<decltype(test_rvalue_reference<void ()>(0)), void (&)()>);      // OK, lvalue reference


template <typename, typename T>
struct select_second_type {
    using type = T;
};
template <typename T>
typename select_second_type<T &&, true_type>::type try_add_rvalue_reference(int);
template <typename T>
false_type try_add_rvalue_reference(...);

template <typename T, bool = decltype(try_add_rvalue_reference<T>(0))::value>
struct add_right_value_reference {
    using type = T &&;
};
template <typename T>
struct add_right_value_reference<T, false> {
    using type = T;
};

static_assert(is_same_v<typename add_right_value_reference<void ()>::type, add_rvalue_reference_t<void ()>>);       // OK
static_assert(is_same_v<typename add_right_value_reference<void ()>::type, void (&&)()>);       // OK, rvlaue reference
c++ c++11 sfinae
1个回答
0
投票

没有函数右值。名义上具有类型

void(&&)()
(或任何“对函数类型的右值引用”)的表达式实际上仍然是左值,而不是 xvalue。

所以你的

decltype(test_rvalue_reference<void ()>(0))
具有类型
void()
(记住,表达式不能有引用类型)并且是一个左值,所以 decltype 产生
void(&)()

将其与

decltype(test_rvalue_reference<int>(0))
进行比较:它具有类型
int
并且是一个 xvalue,因此 decltype 会产生预期的
int&&

© www.soinside.com 2019 - 2024. All rights reserved.