std::add_lvalue_reference、std::add_rvalue_reference
From cppreference.com
| ヘッダ <type_traits> で定義 |
||
| template< class T > struct add_lvalue_reference; |
(1) | (C++11以降) |
| template< class T > struct add_rvalue_reference; |
(2) | (C++11以降) |
T の左辺値参照型または右辺値参照型を作成します。
| 型特性 | ネストされた型 type が参照する型 | |
|---|---|---|
T は 参照可能な型 です。 |
Tは参照可能な型ではない | |
| (1) | T&[1] |
T
|
| (2) | T&&[2] | |
- ↑ この規則は、参照の折りたたみのセマンティクスを反映しています。
- ↑ この規則は、参照の折りたたみのセマンティクスを反映しています。なお、std::add_rvalue_reference<T&>::type は
T&であり、右辺値参照型ではありません。
プログラムがこのページで説明されているテンプレートのいずれかに特殊化を追加する場合、動作は未定義です。
目次 |
[編集] ネストされた型
| 名前 | 定義 |
type
|
上記のように決定されます。 |
[編集] ヘルパー型
| template< class T > using add_lvalue_reference_t = typename add_lvalue_reference<T>::type; |
(C++14以降) | |
| template< class T > using add_rvalue_reference_t = typename add_rvalue_reference<T>::type; |
(C++14以降) | |
[編集] ノート
T& または T&& を直接使用する場合との主な違いは、T が参照可能でない型であってもよいという点です。たとえば、std::add_lvalue_reference<void>::type は void ですが、void& はコンパイルエラーになります。
[編集] 実装候補
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)) {}; |
[編集] 例
このコードを実行
#include <type_traits> using non_ref = int; static_assert(std::is_lvalue_reference_v<non_ref> == false); using l_ref = std::add_lvalue_reference_t<non_ref>; static_assert(std::is_lvalue_reference_v<l_ref> == true); using r_ref = std::add_rvalue_reference_t<non_ref>; static_assert(std::is_rvalue_reference_v<r_ref> == true); using void_ref = std::add_lvalue_reference_t<void>; static_assert(std::is_reference_v<void_ref> == false); int main() {}
[編集] 不具合報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 2101 | C++11 | T が cv または ref 修飾された 関数型 の場合、プログラムは不適格でした。 |
この場合、生成される型は T です。 |
[編集] 関連項目
| (C++11) |
型が左辺値参照または右辺値参照であるかをチェックする (クラステンプレート) |
| (C++11) |
与えられた型から参照を削除する (クラステンプレート) |
| (C++20) |
std::remove_cv と std::remove_reference を組み合わせる (クラステンプレート) |