判断函数返回值是左值引用还是右值引用
LDK Lv4

判断函数返回值是左值引用还是右值引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <iostream>
#include <type_traits>
#include <string>
#include <memory>
using namespace std;

// 用于解析模板参数T的类型名称
// 跨平台的类型名称获取函数, 能正确显示引用
template <typename T>
std::string type_name() {
#if defined(__clang__)
std::string pretty_function = __PRETTY_FUNCTION__;
size_t start = pretty_function.find("T = ") + 4;
size_t end = pretty_function.find("]", start);
return pretty_function.substr(start, end - start);

#elif defined(__GNUC__)
std::string pretty_function = __PRETTY_FUNCTION__;
size_t start = pretty_function.find("T = ") + 4;
size_t end = pretty_function.find(";", start);
return pretty_function.substr(start, end - start);

#elif defined(_MSC_VER)
std::string pretty_function = __FUNCSIG__;
size_t start = pretty_function.find("type_name<") + 10;
size_t end = pretty_function.find(">(void)");
return pretty_function.substr(start, end - start);

#else
#error "Unsupported compiler"
#endif
}

// 专用于判断std::forward返回的是左值引用还是右值引用的函数
template <typename T>
void verify_forward_type(const char *description) {
if constexpr (std::is_lvalue_reference_v<T>) {
std::cout << description << " is an lvalue reference ("
<< (std::is_const_v<std::remove_reference_t<T>> ? "const " : "")
<< "T&)" << std::endl;
} else if constexpr (std::is_rvalue_reference_v<T>) {
std::cout << description << " is an rvalue reference ("
<< (std::is_const_v<std::remove_reference_t<T>> ? "const " : "")
<< "T&&)" << std::endl;
} else {
std::cout << description << " is not a reference (T)" << std::endl;
}
}

// 随便写一个强制返回右值引用的函数, 进行测试
int &&getInt() {
return std::move(10);
}

int main() {
int x = 10;

// 调用右值版本(第二个函数), 指定_Tp为int, 那么返回值为 static_cast<int &&>(__t), 为右值引用
std::cout << type_name<decltype(std::forward<int>(100))>() << std::endl;

// 调用左值版本(第一个函数), 指定_Tp为int&, 那么返回值为 static_cast<int& &&>(__t),
// 引用折叠后为static_cast<int&>(__t), 为左值引用
std::cout << type_name<decltype(std::forward<int &>(x))>() << std::endl;

// 调用左值版本(第一个函数), 指定_Tp为int&&, 那么返回值为 static_cast<int&& &&>(__t),
// 引用折叠后为static_cast<int&&>(__t), 为右值引用
std::cout << type_name<decltype(std::forward<int &&>(x))>() << std::endl;

// 调用右值版本(第二个函数), 指定_Tp为const int&&, 那么返回值为 static_cast<const int&& &&>(__t),
// 引用折叠后为static_cast<const int&&>(__t) 为右值引用
std::cout << type_name<decltype(std::forward<const int &&>(100))>() << std::endl;

// 输出int&&
std::cout << type_name<decltype(getInt())>() << std::endl;

// const int&& 是右值引用
verify_forward_type<decltype(std::forward<const int &&>(x))>("std::forward<const int&&>(x)");

return 0;
}

该代码的输出:

1
2
3
4
5
6
int&&
int&
int&&
const int&&
int&&
std::forward<const int&&>(x) is an rvalue reference (const T&&)
由 Hexo 驱动 & 主题 Keep
本站由 提供部署服务
总字数 74.8k 访客数 访问量