名前空間
変種
操作

decltype 指定子 (C++11 以降)

From cppreference.com
< cpp‎ | language
 
 
C++言語
全般
フロー制御
条件実行文
if
繰り返し文 (ループ)
for
範囲for (C++11)
ジャンプ文
関数
関数宣言
ラムダ式
inline指定子
動的例外仕様 (C++17まで*)
noexcept指定子 (C++11)
例外
名前空間
指定子
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点数
文字 - 文字列 - nullptr (C++11)
ユーザー定義 (C++11)
ユーティリティ
属性 (C++11)
typedef宣言
型エイリアス宣言 (C++11)
キャスト
メモリ確保
クラス
クラス固有の関数プロパティ
explicit (C++11)
static

特殊メンバ関数
テンプレート
その他
 
 

エンティティの宣言された型、または式の型と値カテゴリを検査します。

目次

[編集] 構文

decltype ( entity ) (1)
decltype ( expression ) (2)

[編集] 説明

1) 引数が括弧で囲まれていない id-expression または括弧で囲まれていない クラスメンバーアクセス 式の場合、decltype はこの式によって指定される entity の型を返します。そのようなエンティティがない場合、または引数がオーバーロードされた関数の集合を指定する場合、プログラムは不正な形式です。

引数が 構造化束縛 を指定する括弧で囲まれていない id-expression の場合、decltype は *参照型* (構造化束縛宣言の仕様で説明) を返します。

(C++17以降)

引数が 非型テンプレートパラメータ を指定する括弧で囲まれていない id-expression の場合、decltype はテンプレートパラメータの型を返します (テンプレートパラメータがプレースホルダー型で宣言されている場合、必要な型推論を実行した後)。エンティティがテンプレートパラメータオブジェクト (const オブジェクト) であっても、型は非 const です。

(C++20以降)
2) 引数が型 T のその他の式であり、かつ
a) expression値カテゴリxvalue の場合、decltype は T&& を返します。
b) expression の値カテゴリが lvalue の場合、decltype は T& を返します。
c) expression の値カテゴリが prvalue の場合、decltype は T を返します。

expression がクラス型の prvalue を返す関数呼び出し、または右オペランドがそのような関数呼び出しである コンマ式 である場合、その prvalue に対して一時オブジェクトは導入されません。

(C++17まで)

expression が (括弧で囲まれている可能性のある) 即時呼び出し 以外の prvalue (C++20 以降) の場合、その prvalue から一時オブジェクトは 具現化 されません。そのような prvalue には結果オブジェクトがありません。

(C++17以降)
一時オブジェクトが作成されないため、型は 完全 である必要はなく、利用可能な デストラクタ を持つ必要もなく、抽象 であっても構いません。このルールは副式には適用されません。decltype(f(g())) では、g() は完全な型を持つ必要がありますが、f() はそうである必要はありません。

オブジェクトの名前が括弧で囲まれている場合、それは通常の左辺値式として扱われるため、decltype(x)decltype((x)) はしばしば異なる型になります。

decltype は、ラムダ関連の型やテンプレートパラメータに依存する型のように、標準表記では宣言が困難または不可能な型を宣言するのに役立ちます。

[編集] 備考

機能テストマクロ 規格 機能
__cpp_decltype 200707L (C++11) decltype

[編集] キーワード

decltype

[編集]

#include <cassert>
#include <iostream>
#include <type_traits>
 
struct A { double x; };
const A* a;
 
decltype(a->x) y;       // type of y is double (declared type)
decltype((a->x)) z = y; // type of z is const double& (lvalue expression)
 
template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u) // return type depends on template parameters
                                      // return type can be deduced since 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*)>,
    "Just returning auto isn't perfect forwarding.");
decltype(auto) getRefFwdGood(const int* p) { return getRef(p); }
static_assert(std::is_same_v<decltype(getRefFwdGood), const int&(const int*)>,
    "Returning decltype(auto) perfectly forwards the return type.");
 
// Alternatively:
auto getRefFwdGood1(const int* p) -> decltype(getRef(p)) { return getRef(p); }
static_assert(std::is_same_v<decltype(getRefFwdGood1), const int&(const int*)>,
    "Returning decltype(return expression) also perfectly forwards the return type.");
 
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)>,
        "The type of a lambda function is unique and unnamed");
 
    decltype(f) g = f;
    std::cout << f(3, 3) << ' ' << g(3, 3) << '\n';
}

出力

42 42

[編集] 参照

拡張コンテンツ
  • C++23標準 (ISO/IEC 14882:2024)
  • 9.2.9.5 Decltype 指定子 [dcl.type.decltype]
  • C++20 standard (ISO/IEC 14882:2020)
  • 9.2.8.4 Decltype 指定子 [dcl.type.decltype]
  • C++17 standard (ISO/IEC 14882:2017)
  • TBD Decltype 指定子 [dcl.type.decltype]
  • C++14 standard (ISO/IEC 14882:2014)
  • TBD Decltype 指定子 [dcl.type.decltype]
  • C++11 standard (ISO/IEC 14882:2011)
  • TBD Decltype 指定子 [dcl.type.decltype]

[編集] 関連項目

auto 指定子 (C++11) 式から推論される型を指定します [編集]
(C++11)
評価されない文脈で使用するために、テンプレート型引数のオブジェクトへの参照を取得する
(関数テンプレート) [編集]
(C++11)
2つの型が同じであるかをチェックする
(クラステンプレート) [編集]
C ドキュメント ( typeof について)
English 日本語 中文(简体) 中文(繁體)