名前空間
変種
操作

std::add_lvalue_reference、std::add_rvalue_reference

From cppreference.com
< cpp‎ | types
 
 
メタプログラミングライブラリ
型特性
型のカテゴリ
(C++11)
(C++11)(DR*)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11) 
(C++11)
(C++11)
型のプロパティ
(C++11)
(C++11)
(C++14)
(C++11)(C++26で非推奨)
(C++11)(C++20まで*)
(C++11)(C++20で非推奨)
(C++11)
型特性定数
メタ関数
(C++17)
サポートされている操作
関係とプロパティクエリ
型の変更
(C++11)(C++11)(C++11)
add_lvalue_referenceadd_rvalue_reference
(C++11)(C++11)

型の変換
(C++11)(C++23で非推奨)
(C++11)(C++23で非推奨)
(C++11)
(C++11)(C++20まで*)(C++17)

(C++11)
(C++17)
コンパイル時有理数演算
コンパイル時整数シーケンス
 
ヘッダ <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]
  1. この規則は、参照の折りたたみのセマンティクスを反映しています。
  2. この規則は、参照の折りたたみのセマンティクスを反映しています。なお、std::add_rvalue_reference<T&>::typeT& であり、右辺値参照型ではありません。

プログラムがこのページで説明されているテンプレートのいずれかに特殊化を追加する場合、動作は未定義です。

目次

[編集] ネストされた型

名前 定義
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>::typevoid ですが、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 Tcv または ref 修飾された 関数型 の場合、プログラムは不適格でした。 この場合、生成される型は T です。

[編集] 関連項目

型が左辺値参照または右辺値参照であるかをチェックする
(クラステンプレート) [編集]
与えられた型から参照を削除する
(クラステンプレート) [編集]
std::remove_cvstd::remove_reference を組み合わせる
(クラステンプレート) [編集]
English 日本語 中文(简体) 中文(繁體)