コンテンツにスキップ

最終更新:2026-10-12

C++ decltype 型推論

著者について:

個人公式アカウント:

wechat

1.基本的な使い方

decltypeの構文は次の通りです:

decltype (expression)

ここで括弧は必須です。decltypeの役割は「式の型を問い合わせる」ことなので、上の文の効果は、expressionという式の型を返すことです。注意すべきは、decltypeはあくまで式の型を「問い合わせる」だけであり、式を「評価」するわけではないということです。

1.1 式の型を推論する

int i = 4;
decltype(i) a; //推导结果为int。a的类型为int。

1.2 using/typedefと併用して、型を定義する。

using size_t = decltype(sizeof(0));//sizeof(a)的返回值为size_t类型
using ptrdiff_t = decltype((int*)0 - (int*)0);
using nullptr_t = decltype(nullptr);
vector<int >vec;
typedef decltype(vec.begin()) vectype;
for (vectype i = vec.begin; i != vec.end(); i++)
{
//...
}

このようにautoと同じく、コードの可読性を高められます。

1.3 匿名型を再利用する

C++では、ときどき次のような匿名型に出会います:

struct 
{
    int d ;
    double b;
}anon_s;

decltypeを借りれば、この匿名の構造体を再び利用できます:

decltype(anon_s) as ;//定义了一个上面匿名的结构体

1.4 ジェネリックプログラミングでautoと組み合わせ、関数の戻り値の型を追跡する

これがdecltypeの最大の用途です。

template <typename T>
auto multiply(T x, T y)->decltype(x*y)
{
    return x*y;
}

完全なコードはこちら:decltype.cpp

2.判別ルール

decltype(e)については、その判別結果は以下の条件の影響を受けます:

eが括弧で囲まれていない識別子式またはクラメンバアクセス式である場合、decltype(e)はeが名指す実体の型になります。また、eがオーバーロードされた関数である場合はコンパイルエラーになります。 それ以外の場合、eの型をTとすると、eがxvalue(破棄予定値)であれば、decltype(e)はT&&になります それ以外の場合、eの型をTとすると、eが左値であれば、decltype(e)はT&になります。 それ以外の場合、eの型をTとすると、decltype(e)はTになります。

識別子とは、キーワードやリテラルなどコンパイラが必要とするトークンを除いた、プログラマ自身が定義したトークンのことで、単一の識別子に対応する式が識別子式です。例えば:

int arr[4]
この場合arrは識別子式ですが、arr[3]+0はそうではありません。

例を以下に示します:

int i = 4;
int arr[5] = { 0 };
int *ptr = arr;
struct S{ double d; }s ;
void Overloaded(int);
void Overloaded(char);//重载的函数
int && RvalRef();
const bool Func(int);

//规则一:推导为其类型
decltype (arr) var1; //int[] 标记符表达式

decltype (ptr) var2;//int *  标记符表达式

decltype(s.d) var3;//doubel 成员访问表达式

//decltype(Overloaded) var4;//重载函数。编译错误。

//规则二:将亡值。推导为类型的右值引用。

decltype (RvalRef()) var5 = 1;

//规则三:左值,推导为类型的引用。

decltype ((i))var6 = i;     //int&

decltype (true ? i : i) var7 = i; //int&  条件表达式返回左值。

decltype (++i) var8 = i; //int&  ++i返回i的左值。

decltype(arr[5]) var9 = i;//int&. []操作返回左值

decltype(*ptr)var10 = i;//int& *操作返回左值

decltype("hello")var11 = "hello"; //const char(&)[9]  字符串字面常量为左值,且为const左值。


//规则四:以上都不是,则推导为本类型

decltype(1) var12;//const int

decltype(Func(1)) var13=true;//const bool

decltype(i++) var14 = i;//int i++返回右值

学習参考:https://www.cnblogs.com/QG-whz/p/4952980.html

関連トピック

コメント