std::declval
From cppreference.com
| ヘッダ <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-used された場合、プログラムは不正形式となります。
目次 |
[編集] Parameters
(なし)
[編集] Return value
評価されることはないため、値を返すことはありません。戻り値の型は T&& (参照の折り畳み規則が適用されます) です。ただし、T が (cv 修飾されている可能性のある) void の場合は、戻り値の型は T になります。
[編集] Notes
std::declval は、テンプレートパラメータとして受け入れられる型が共通のコンストラクタを持たないものの、戻り値の型が必要な同じメンバ関数を持つ場合に、テンプレートで一般的に使用されます。
[編集] Possible implementation
template<typename T> typename std::add_rvalue_reference<T>::type declval() noexcept { static_assert(false, "declval not allowed in an evaluated context"); } |
[編集] Example
このコードを実行
#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; // type of n1 is int decltype(std::declval<Default>().foo()) n2 = 1; // same // decltype(NonDefault().foo()) n3 = n1; // error: no default constructor decltype(std::declval<NonDefault>().foo()) n3 = n1; // type of n3 is int std::cout << "n1 = " << n1 << '\n' << "n2 = " << n2 << '\n' << "n3 = " << n3 << '\n'; }
出力
n1 = 1 n2 = 1 n3 = 1
[編集] See also
decltype 指定子(C++11) |
式またはエンティティの型を取得します。 |
| (C++11)(C++20で削除)(C++17) |
呼び出し可能オブジェクトを引数のセットで呼び出した結果の型を推論する (クラステンプレート) |