std::add_lvalue_reference, std::add_rvalue_reference
出自cppreference.com
| 在標頭 <type_traits> 定義
|
||
| |
(1) | (C++11 起) |
| |
(2) | (C++11 起) |
創建 T 的左值或右值引用類型。
1) 如果
T 是一個沒有 cv 或引用限定符的函數類型,或者是一個對象類型,則提供成員 typedef type,其類型為 T&。如果 T 是某個類型 U 的右值引用,則 type 為 U&。否則,type 為 T。2) 如果
T 是一個沒有 cv 或引用限定符的函數類型,或者是一個對象類型,則提供成員 typedef type,其類型為 T&&,否則 type 為 T。如果程序添加了此頁面上描述的任何模板的特化,那麼行為未定義。
成員類型
| 名字 | 定義 |
type
|
T 的引用,或當「T 的引用」無效時為 T
|
輔助類型
| |
(C++14 起) | |
| |
(C++14 起) | |
註解
這些類型變換遵循引用摺疊規則:
std::add_lvalue_reference<T&>::type為T&std::add_lvalue_reference<T&&>::type為T&std::add_rvalue_reference<T&>::type為T&std::add_rvalue_reference<T&&>::type為T&&
使用這些類型特徵與直接使用 T& 的主要區別是 std::add_lvalue_reference<void>::type 是 void,而 void& 會導致編譯錯誤。
可能的實現
namespace detail
{
template<class T>
struct type_identity { using type = T; }; // 或者使用 std::type_identity(C++20 起)
template<class T> // 注意 `cv void&` 是替换失败
auto try_add_lvalue_reference(int) -> type_identity<T&>;
template<class T> // 处理 T = cv void 的情况
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)) {};
|
示例
運行此代碼
#include <type_traits>
int main()
{
using non_ref = int;
using l_ref = typename std::add_lvalue_reference_t<non_ref>;
static_assert(std::is_lvalue_reference_v<l_ref>);
using r_ref = typename std::add_rvalue_reference_t<non_ref>;
static_assert(std::is_rvalue_reference_v<r_ref>);
using void_ref = std::add_lvalue_reference_t<void>;
static_assert(!std::is_reference_v<void_ref>);
}
缺陷報告
下列更改行為的缺陷報告追溯地應用於以前出版的 C++ 標準。
| 缺陷報告 | 應用於 | 出版時的行為 | 正確行為 |
|---|---|---|---|
| LWG 2101 | C++11 | 規定這些變換特徵 產生對 cv/引用限定的函數類型的引用。 |
產生 cv/引用限定的函數類型自身。 |
參閱
(C++11) |
檢查類型是否為左值引用 或右值引用 (類模板) |
(C++11) |
從給定類型移除引用 (類模板) |
(C++20) |
將 std::remove_cv 與 std::remove_reference 結合 (類模板) |