decltype
specifier
(since C++11)
エンティティの宣言された型、または式の型と値カテゴリを検査します。
目次 |
構文
decltype (
エンティティ
)
|
(1) | ||||||||
decltype (
式
)
|
(2) | ||||||||
説明
|
引数が structured binding を命名する括弧で囲まれていない id-expression の場合、decltypeは referenced type (構造化バインディング宣言の仕様で記述されている)を生成する。 |
(C++17以降) |
|
引数が constant template parameter を命名する括弧で囲まれていない id-expression の場合、decltypeはテンプレートパラメータの型を生成する(テンプレートパラメータがプレースホルダ型で宣言されている場合、必要な型推論を実行した後)。entityがテンプレートパラメータオブジェクト(constオブジェクト)であっても、型は非constとなる。 |
(C++20以降) |
T
のその他の式である場合、かつ
|
expression がクラス型のprvalueを返す関数呼び出し、または右辺オペランドがそのような関数呼び出しである コンマ式 の場合、そのprvalueに対して一時オブジェクトは導入されない。 |
(C++17まで) |
|
expression が(丸括弧で囲まれた可能性のある) 即時呼び出し 以外のprvalueである場合、そのprvalueから一時オブジェクトは 実体化 されない:そのようなprvalueは結果オブジェクトを持たない。 |
(C++17以降) |
オブジェクトの名前が括弧で囲まれている場合、通常の左辺値式として扱われることに注意してください。したがって、 decltype ( x ) と decltype ( ( x ) ) はしばしば異なる型になります。
decltype
は、ラムダ関連の型やテンプレートパラメータに依存する型など、標準的な記法では宣言が困難または不可能な型を宣言する際に有用です。
注記
| 機能テストマクロ | 値 | 規格 | 機能 |
|---|---|---|---|
__cpp_decltype
|
200707L
|
(C++11) | decltype |
キーワード
例
#include <cassert> #include <iostream> #include <type_traits> struct A { double x; }; const A* a; decltype(a->x) y; // yの型はdouble(宣言された型) decltype((a->x)) z = y; // zの型はconst double&(左辺値式) template<typename T, typename U> auto add(T t, U u) -> decltype(t + u) // 戻り値の型はテンプレートパラメータに依存 // C++14以降では戻り値の型は推論可能 { return t + u; } const int& getRef(const int* p) { return *p; } static_assert(std::is_same_v<decltype(getRef), const int&(const int*)>); auto getRefFwdBad(const int* p) { return getRef(p); } static_assert(std::is_same_v<decltype(getRefFwdBad), int(const int*)>, "単にautoを返すだけでは完全転送にはならない"); decltype(auto) getRefFwdGood(const int* p) { return getRef(p); } static_assert(std::is_same_v<decltype(getRefFwdGood), const int&(const int*)>, "decltype(auto)を返すことで戻り値の型を完全転送する"); // 代替案: auto getRefFwdGood1(const int* p) -> decltype(getRef(p)) { return getRef(p); } static_assert(std::is_same_v<decltype(getRefFwdGood1), const int&(const int*)>, "decltype(戻り値式)を返すことでも戻り値の型を完全転送する"); int main() { int i = 33; decltype(i) j = i * 2; static_assert(std::is_same_v<decltype(i), decltype(j)>); assert(i == 33 && 66 == j); auto f = [i](int av, int bv) -> int { return av * bv + i; }; auto h = [i](int av, int bv) -> int { return av * bv + i; }; static_assert(!std::is_same_v<decltype(f), decltype(h)>, "ラムダ関数の型は一意で名前を持たない"); decltype(f) g = f; std::cout << f(3, 3) << ' ' << g(3, 3) << '\n'; }
出力:
42 42
参考文献
| 拡張コンテンツ |
|---|
|
|
このセクションは不完全です
理由:修正が必要です。参照: Talk: Wrong References . |
関連項目
auto
指定子
(C++11)
|
式から推論される型を指定する |
|
(C++11)
|
未評価コンテキストで使用するためのテンプレート型引数のオブジェクトへの参照を取得する
(関数テンプレート) |
|
(C++11)
|
2つの型が同じかどうかをチェックする
(クラステンプレート) |
|
Cドキュメント
for
typeof
|
|