decltype 指定子
提供: cppreference.com
エンティティの宣言された型または式の型と値カテゴリを調べます。
目次 |
[編集] 構文
decltype ( entity )
|
(1) | (C++11以上) | |||||||
decltype ( expression )
|
(2) | (C++11以上) | |||||||
[編集] 説明
(C++17以上) | |
2) 引数が非型テンプレート引数を表す括弧で囲まれていない識別子式の場合、 decltype はそのテンプレート引数の型 (そのテンプレート引数がプレースホルダ型を用いて宣言されている場合はあらゆる必要な型推定を行った後の) になります。
|
(C++20以上) |
3) 引数が括弧で囲まれていない識別子式または括弧で囲まれていないクラスメンバアクセス式の場合、 decltype はその式によって表される entity の型になります。 そのようなエンティティがない場合、または引数がオーバーロード関数の集合を表す場合、プログラムは ill-formed です。
4) 引数がそれ以外の任意の
T
型の式の場合、かつb) expression の値カテゴリが lvalue の場合、 decltype は
T&
になります。c) expression の値カテゴリが prvalue の場合、 decltype は
T
になります。
expression がクラス型の prvalue を返す関数呼び出しか、右側の被演算子がそのような関数呼び出しであるコンマ式の場合、一時オブジェクトはその prvalue に対して導入されません。 |
(C++17未満) |
expression が即時呼び出し (括弧で囲った場合を含みます) 以外の (C++20以上) prvalue である場合、一時オブジェクトはその prvalue から具体化されません (そのような prvalue は結果オブジェクトを持ちません)。 |
(C++17以上) |
型は完全である必要も利用可能なデストラクタを持つ必要もなく、抽象であっても構いません。 このルールは部分式には適用されません。 例えば decltype(f(g())) の場合、 g() は完全型でなければなりませんが、 f() はその必要はありません。
オブジェクトの名前が括弧で囲まれている場合は普通の lvalue 式として扱われるため、 decltype(x) と decltype((x)) はしばしば異なる型となることに注意してください。
decltype
は、ラムダに関連する型やテンプレート引数に依存する型のような、標準の記法を用いて宣言することが難しいまたは不可能な型を宣言するときに便利です。
[編集] キーワード
[編集] 例
Run this code
#include <iostream> struct A { double x; }; const A* a; decltype(a->x) y; // y の型は double です (宣言された型)。 decltype((a->x)) z = y; // z の型は const double& です (lvalue 式)。 template<typename T, typename U> auto add(T t, U u) -> decltype(t + u) // 戻り値の型はテンプレート引数に依存します。 // C++14 からは戻り値の型を推定することもできます。 { return t+u; } int main() { int i = 33; decltype(i) j = i * 2; std::cout << "i = " << i << ", " << "j = " << j << '\n'; auto f = [](int a, int b) -> int { return a * b; }; decltype(f) g = f; // ラムダ関数の型は一意かつ無名です。 i = f(2, 2); j = g(3, 3); std::cout << "i = " << i << ", " << "j = " << j << '\n'; }
出力:
i = 33, j = 66 i = 4, j = 9
[編集] 関連項目
auto 指定子 | 式によって定義される型を指定します (C++11) |
(C++11) |
未評価文脈で使用するための引数への参照を取得します (関数テンプレート) |