decltype 型指定子
decltype の型指定子が指定された式の種類について説明します。decltype の型指定子はauto キーワード とともにテンプレート ライブラリを記述する開発者に有効です。戻り値の型はテンプレートの引数の型に応じたテンプレート関数を宣言するために auto と decltype を使用します。別の関数呼び出しをラップするテンプレート関数を宣言するにはを使用 auto と decltypeラップされた関数の戻り値の型を返します。
decltype( expression )
パラメーター
パラメーター |
Description |
---|---|
expression |
任意の式を指定します。詳細については、「式 (C++)」を参照してください。 |
戻り値
expression パラメーターの型。
解説
decltype の型指定子はVisual C++ 2010 以降のバージョンでサポートされネイティブ コードまたはマネージ コードで使用できます。
コンパイラは expression のパラメーターの型が決定次の規則を使用します。
expression のパラメーターが識別子または クラス メンバーのアクセス 場合decltype(expression) は expression によって指定されるエンティティの種類です。このようなエンティティまたは expression のパラメーター名は一連のオーバーロードされた関数はない場合コンパイラがエラー メッセージを生成します。
expression のパラメーターは関数またはオーバーロードされた関数の呼び出しはdecltype(expression) は関数の戻り値の型です。オーバーロードされた演算子を囲むかっこは無視されます。
expression のパラメーターが rvalue 場合decltype(expression) は expression の型です。expression のパラメーターが 左辺値 場合decltype(expression) は expression の種類を lvalue 参照 です。
次のコード例に decltype の型指定子の使用例を示します。最初に次のステートメントを記述したとします。
int var;
const int&& fx();
struct A { double x; }
const A* a = new A();
次に以下の表の decltype の 4 種類のステートメントによって返される型をチェックします。
ステートメント |
種類 |
説明 |
---|---|---|
decltype(fx()); |
const int&& |
const int への rvalue 参照。 |
decltype(var); |
int |
変数 var の型。 |
decltype(a->x); |
double |
メンバー アクセスの種類。 |
decltype((a->x)); |
const double& |
かっこの内側のステートメントをメンバー アクセスの代わりに式として評価されます。をaポインターとして宣言constされているため型はへの参照ですconst double。 |
Decltype と自動
戻り値の型はテンプレートの引数の型に応じたテンプレート関数を宣言するためにauto のキーワードとともに decltypeの型指定子を使用します。たとえばテンプレート関数の戻り値の型はテンプレートの引数の型に応じた次のコード例について検討します。コード例では 不明 のプレースホルダーは戻り値の型を指定できないことを示します。
template<typename T, typename U>
UNKNOWNfunc(T&& t, U&& u){ return t + u; };
decltype の型指定子の概要はその式の型を取得することがテンプレート関数ができます。後で説明する 遅延指定した 戻り値の型を宣言するには 代替関数宣言の構文 auto のキーワードと decltype の型指定子を使用します。遅延指定した戻り値の型はと宣言されるコードのコンパイル時に決定ではなくです。
次のプロトタイプが代替関数宣言の構文について説明します。const と volatile の修飾子はthrow例外の指定 省略可能であることに注意してください。function_body のプレースホルダーは関数の動作を指定する複合ステートメントを表します。でコーディングの推奨手順としてdecltype のステートメントの 式 のプレースホルダーは function_body で return のステートメントである場合指定する式に一致する必要があります。
autofunction_name( パラメーター opt)constoptvolatileopt − >decltype( 式 )throwopt{function_body};
次のコード例ではmyFunc テンプレート関数の遅延指定した戻り値の型は t と u のテンプレート引数の型によって決まります。でコーディングの推奨手順としてこのコード例では 完全転送を サポートする forward の関数テンプレートを使用してrvalue 参照を返します。詳細については、「右辺値参照宣言子: &&」を参照してください。
template<typename T, typename U>
auto myFunc(T&& t, U&& u) -> decltype (forward<T>(t) + forward<U>(u))
{ return forward<T>(t) + forward<U>(u); };
Decltype とコピーの関数
他の関数にコピーするには関数を呼び出します。引数を一つずつそれらの引数を含む式の結果を示します。別の関数にテンプレート関数。さらにコピー関数の戻り値などの関数を呼び出した結果。この場合コピー関数の戻り値の型はラップされた関数の戻り値の型と同じです。
このシナリオではdecltype の型指定子がない場合適切な型の式を使用できません。decltype の型指定子は必要な情報をかに関係なく関数の戻り値型参照されるため一般的なコピーの関数を有効にします。コピーの関数のコード例では前の myFunc テンプレート関数の例を参照してください。
使用例
次のコード例はテンプレート関数 Plus() の遅延指定した戻り値の型を宣言します。Plus の関数は operator+ のオーバーロードとの 2 種類のオペランドを処理します。その結果加算演算子 (+) の解釈と Plus 関数の戻り値の型は関数の引数の型によって異なります。
// decltype_1.cpp
// compile with: /EHsc
//
#include "stdafx.h"
#include <iostream>
#include <string>
#include <utility>
#include <iomanip>
using namespace std;
template<typename T1, typename T2>
auto Plus(T1&& t1, T2&& t2) ->
decltype(forward<T1>(t1) + forward<T2>(t2))
{
return forward<T1>(t1) + forward<T2>(t2);
}
class X
{
friend X operator+(const X& x1, const X& x2)
{
return X(x1.m_data + x2.m_data);
}
public:
X(int data) : m_data(data) {}
int Dump() const { return m_data;}
private:
int m_data;
};
int main()
{
// Integer
int i = 4;
cout <<
"Plus(i, 9) = " <<
Plus(i, 9) << endl;
// Floating point
float dx = 4.0;
float dy = 9.5;
cout <<
setprecision(3) <<
"Plus(dx, dy) = " <<
Plus(dx, dy) << endl;
// String
string hello = "Hello, ";
string world = "world!";
cout << Plus(hello, world) << endl;
// Custom type
X x1(20);
X x2(22);
X x3 = Plus(x1, x2);
cout <<
"x3.Dump() = " <<
x3.Dump() << endl;
}
出力
このコード例では次の結果が返されます。
13
13.5
Hello World!
42
必要条件
Visual C++ 2010 以降のバージョン。