cpp*_*cpp 2 c++ std type-traits c++-templates
使用 type_identity 作为尾随返回类型的目的是什么?
https://en.cppreference.com/w/cpp/types/add_reference提供了以下可能的 add_lvalue_reference 和 add_rvalue_reference 实现
namespace detail {
template <class T>
struct type_identity { using type = T; }; // or use std::type_identity (since C++20)
template <class T> // Note that `cv void&` is a substitution failure
auto try_add_lvalue_reference(int) -> type_identity<T&>;
template <class T> // Handle T = cv void case
auto try_add_lvalue_reference(...) -> type_identity<T>;
template <class T>
auto try_add_rvalue_reference(int) -> type_identity<T&&>;
template <class T>
auto try_add_rvalue_reference(...) -> type_identity<T>;
} // namespace detail
template <class T>
struct add_lvalue_reference
: decltype(detail::try_add_lvalue_reference<T>(0)) {};
template <class T>
struct add_rvalue_reference
: decltype(detail::try_add_rvalue_reference<T>(0)) {};
Run Code Online (Sandbox Code Playgroud)
我在不使用 type_identity 的情况下尝试了自己的实现,并且它按预期工作。我错过了什么?
namespace detail {
template <class T> // Note that `cv void&` is a substitution failure
auto try_add_lvalue_reference(int) -> T&;
template <class T> // Handle T = cv void case
auto try_add_lvalue_reference(...) -> T;
template <class T>
auto try_add_rvalue_reference(int) -> T&&;
template <class T>
auto try_add_rvalue_reference(...) -> T;
} // namespace detail
template <class T>
struct add_lvalue_reference {
using type = decltype(detail::try_add_lvalue_reference<T>(0));
};
template <class T>
struct add_rvalue_reference {
using type = decltype(detail::try_add_rvalue_reference<T>(0));
};
int main()
{
if (std::is_same_v<add_lvalue_reference<int>::type, int&>) {
std::cout << "add_lvalue_reference int same\n";
} else {
std::cout << "add_lvalue_reference int different\n";
}
if (std::is_same_v<add_lvalue_reference<void>::type, void>) {
std::cout << "add_lvalue_reference void same\n";
} else {
std::cout << "add_lvalue_reference void different\n";
}
if (std::is_same_v<add_rvalue_reference<int>::type, int&&>) {
std::cout << "add_rvalue_reference int same\n";
} else {
std::cout << "add_rvalue_reference int different\n";
}
if (std::is_same_v<add_rvalue_reference<void>::type, void>) {
std::cout << "add_rvalue_reference void same\n";
} else {
std::cout << "add_rvalue_reference void different\n";
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
对于 cv 限定的 void 并尝试添加对函数类型的右值引用或对函数类型的右值引用,您的实现失败(因为 是decltype(function-returning-cv-void())未限定的void并且decltype(function-returning-rvalue-reference-to-function())是对所述函数类型的左值引用,因为没有函数右值)。
有些类型是不可引用的,也不能从函数返回,例如 cv 限定的函数类型。
// Your functions
add_lvalue_reference<const void>
-> void
add_rvalue_reference<int(int param)>
-> int(&)(int param)
add_rvalue_reference<int(&&)(int param)>
-> int(&)(int param)
add_lvalue_reference<int(int param) const>
(fails to compile)
// Expected types
add_lvalue_reference<const void>
-> const void
add_rvalue_reference<int(int param)>
-> int(&&)(int param)
add_rvalue_reference<int(&&)(int param)>
-> int(&&)(int param)
add_lvalue_reference<int(int param) const>
-> int(int param) const
Run Code Online (Sandbox Code Playgroud)