C++decltypeタイプの引数
このシリーズの文章は@yhl_からなります.leo製品、転載は出所を明記してください.
記事のリンク:http://blog.csdn.net/yhl_leo/articale/detail/50865552
1基本文法
構文:は、 は、 は、 以下のコードの例を示します.
タイプ
コメント
2
一方、表式の内容が参照解除操作である場合、
3トップレベルのconstを処理する方法と、引用の仕方が異なる(参照:C+autタイプの引数) テンプレート関数の返却タイプ は、C+11において、戻りタイプに尾行された は、C+14において、バックタイプの 例えば、求和テンプレート関数を定義します.
ソースコードの一部を添付します. Microsoft Developer Network:decltype(C+) C++Primer(第五版)》Stnley B.Lippman.
記事のリンク:http://blog.csdn.net/yhl_leo/articale/detail/50865552
1基本文法
decltype
タイプの引数は、指定された式のタイプを生成します.このプロセスでは、コンパイラは式を解析し、そのタイプを得るが、式の値は実際に計算されない.構文:
decltype( expression )
コンパイラは、以下の規則を使用して、expression
パラメータの種類を決定する.expression
パラメータが識別子またはクラスメンバーアクセスである場合、decltype(expression)
はexpression
によって命名されたエンティティのタイプである.このようなエンティティが存在しない場合、またはexpression
パラメータのセットがリロード関数として命名されると、コンパイラはエラーメッセージを生成する.expression
パラメータが、1つの関数または1つのリロード演算子関数に対する呼び出しである場合、decltype(expression)
は、関数の返却タイプである.演算子の両側の括弧は無視されます.expression
パラメータが右の値である場合、decltype(expression)
はexpression
タイプである.expression
パラメータが左値である場合、decltype(expression)
は左値参照タイプのexpression
である.int var;
const int&& fx();
struct A { double x; }
const A* a = new A();
語句タイプ
コメント
decltype(fx());
const int &&
const int
decltype(var);
int
変数var
のタイプdecltype(a->x);
double
メンバーアクセスのタイプdecltype((a->x));
const double&
内部括弧は、メンバーがアクセスして計算するのではなく、表現として文をもたらします.a
は、const
ポインタであると宣言しているので、タイプはconst double
への参照である.2
decltype
と引用decltype
が使用する表現が変数でない場合、decltype
は式の結果に対応するタイプを返します.しかし、いくつかの表現は、1つの参照タイプをdecltype
に返します.一般的に、このような状況が発生した場合、この表式の結果オブジェクトは、1つの割当文の左の値として使用できることを意味する.// decltype
int i = 42, *p = &i, &r = i;
decltype(r + 0) b; // OK, int, b ( ) int
decltype(*p) c; // Error, c int&,
r
は1つの参照であるので、decltype(r)
の結果は参照タイプであり、結果のタイプがr
によって指定されるタイプであれば、r
を表現の一部としてもよく、r+0
のように、この表現の結果は1つの参照ではなく具体的な値になることは明らかである.一方、表式の内容が参照解除操作である場合、
decltype
は参照タイプを得る.私たちがよく知っているように、参照解除ポインタは、ポインタが指すオブジェクトを得ることができ、また、このオブジェクトに値を割り当てることができるので、decltype(*p)
の結果のタイプはint&
であって、int
ではない.3
decltype
及びauto
decltype
が使用する表現が変数である場合、decltype
は、トップconst
と参照を含む変数のタイプを返します.const int ci = 0, &cj = ci;
decltype(ci) x = 0; // x const int
decltype(cj) y = x; // y const int&,y x
decltype(cj) z; // Error, z ,
decltype
の結果のタイプは、表現形式と密接に関係している.decltype
で使用される参照に対して、変数名に括弧がセットされている場合、得られたタイプと括弧がない場合は異なる.decltype
が括弧を使わない変数を使用している場合、結果はその変数の種類です.変数に1つまたは複数の括弧を加えると、コンパイラは表現として扱われます.decltype((i)) d; // Error, d int&,
decltype(i) e; // OK, e int
decltype
タイプの引数とauto
キーワードを使用して、戻りタイプがそのテンプレートパラメータタイプに依存するテンプレート関数を宣言することができる.decltype(auto)
を有しないで返しタイプを宣言することができ、その戻りタイプはテンプレートパラメータタイプに依存するテンプレート関数である.//C++11
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); };
//C++14
template<typename T, typename U>
decltype(auto) myFunc(T&& t, U&& u)
{ return forward<T>(t) + forward<U>(u); };
(forward
:パラメータが右または右の値で参照されている場合、条件付きでそのパラメータを右の値に強制的に変換する.)ソースコードの一部を添付します.
#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;
}
実行結果は:Plus(i, 9) = 13
Plus(dx, dy) = 13.5
Hello, world!
x3.Dump() = 42
参考資料: