std::declval
ja.cppreference.net より
| ヘッダ <utility>
|
||
template< class T >
typename std::add_rvalue_reference<T>::type declval() noexcept;
|
で定義 (C++11 以上) (C++14 まで) (未評価のみ) |
|
template< class T >
std::add_rvalue_reference_t<T> declval() noexcept;
|
(C++14 以上) (未評価のみ) |
|
未評価文脈に現れる式を記述するためのヘルパーテンプレート。典型的には decltype の被演算子です。未評価文脈では、このヘルパーテンプレートは任意の型 T (不完全型でも可) をその型の式に変換し、コンストラクタを経由せずに T のメンバ関数を使用できるようにします。
std::declval は 未評価文脈でのみ使用でき、定義されている必要はありません。この関数を含む式を評価することはエラーです。正式には、この関数が ODR使用された場合、プログラムは ill-formed です。
パラメータ
(なし)
戻り値
評価されることはなく、したがって値を返すことはありません。戻り値の型は、
T&&
(参照縮約規則が適用されます)ですが、
T
が(CV修飾されている可能性のある)
void
である場合を除きます。その場合、戻り値の型は
T
です。
注記
std::declval
は、共通のコンストラクタを持たないが、同じメンバ関数を持ち、その戻り値の型が必要とされるテンプレートパラメータが許容されるテンプレートで一般的に使用されます。
実装例
template<typename T> typename std::add_rvalue_reference<T>::type declval() noexcept { static_assert(false, "declval not allowed in an evaluated context"); } |
例
このコードを実行
#include <iostream> #include <utility> struct Default { int foo() const { return 1; } }; struct NonDefault { NonDefault() = delete; int foo() const { return 1; } }; int main() { decltype(Default().foo()) n1 = 1; // n1の型はint decltype(std::declval<Default>().foo()) n2 = 1; // 同じ // decltype(NonDefault().foo()) n3 = n1; // エラー: デフォルトコンストラクタが存在しない decltype(std::declval<NonDefault>().foo()) n3 = n1; // n3の型はint std::cout << "n1 = " << n1 << '\n' << "n2 = " << n2 << '\n' << "n3 = " << n3 << '\n'; }
出力:
n1 = 1 n2 = 1 n3 = 1
関連項目
decltype
指定子
(C++11)
|
式またはエンティティの型を取得する |
|
(C++11)
(C++20で削除)
(C++17)
|
呼び出し可能オブジェクトを引数セットで呼び出した結果の型を推論する
(クラステンプレート) |