C++ 利用 forwarding reference 识别表达式的值类别
2025-01-29 13:03 CST
forwarding reference 是 TAD(template argument deduction) 的一条特殊规则。当函数的模板参数是 T&&
时:
- 如果传入的函数实参是
lvalue
,则T
为左值引用。 - 如果传入的函数实参是
rvalue
,则T
为对应类型。 例如:
1
2
3
4
5
6
7
8
9
template<class T>
void f(T&& v) {}
int main()
{
f(11);
int x = 1;
f(x);
}
f(11)
的参数 11
是 rvalue,所以 T
直接为 int
。这样 T&&
就恰为 int&&
。右值引用 int&&
可以绑定右值 11
。
f(x)
的参数 x
是 lvalue,所以 T
为 int&
。然后根据引用折叠原理,T&&
为 int&
。左值引用 int&
可以绑定左值 x
。
这样,在函数 f(T&& v)
内,v
的绑定的值类别可以根据 T
是否为左值引用进行判断。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <type_traits>
#include <utility>
template<class T>
constexpr bool is_lvalue(T&& v)
{
return std::is_lvalue_reference_v<T>;
}
template<class T>
constexpr bool is_rvalue(T&& v)
{
return !is_lvalue(std::forward<T>(v));
}
int main()
{
int x = 3;
static_assert(is_lvalue(x));
static_assert(is_rvalue(11));
}
这种方法只能区分 lvalue 和 rvalue,无法区分 xvalue。如果想还是使用 decltype((x)) 来判断。
C++ 利用 forwarding reference 识别表达式的值类别 by mkckr0 is licensed under CC BY-NC-ND 4.0