2026/01/15(木)cpprefjpを読もう。【decltype】

C++11 decltype [N2343] cpprefjp

仕様

C++11の機能、指定した式の型を取得できる。

typeofと何が違うのかと思ったのだが、typeofは非標準な仕様らしい。
知らなかった...
C言語ではC23にて標準仕様に取り込まれたらしい。(めちゃ最近の話だ...)

typeof演算子 in 標準C - yohhoyの日記 - はてなブログ
typeofと比較して仕様の違い。
  1. 参照の扱い

    • decltypeはオペランドの型にある参照を保存する。
    • typeofはオペランドの型にある参照を外す。
      wandbox
      左辺値への参照型に対して型を取得した場合、
      decltype(int&)int&を示し、
      typeof(int&)intを示す
  2. 使用可能な場所

    • typeofは変数宣言時のみ使用可能
    • decltypeは型名が使用できる場所はどこでも使用可能
  3. オペランドの種類

    • typeofは式と型を使用可能
      例) typeof(int)typeof(a + b)

    • decltypeは式のみ使用可能
      例) decltype(a + b)
追記

C++11の以下機能の組み合わせで使用しているのを見かける
変数の型推論のための auto
decltype
戻り値の型を後置する関数宣言構文

auto function(int a, int b) -> decltype(a + b)
{
    return a + b;
}

2026/01/14(水)cpprefjpを読もう。【変数の型推論のためのauto】

C++11 変数の型推論のためのauto [N1984] cpprefjp

C++11からの機能で、変数宣言時に具体的な型名を省略して宣言できる。
個人的にはユーザー定義クラスを使用する時に使用する印象。
ある程度短い型名ではわざわざ使わないかも。uint16_tとか...

auto container = std::vector<std::pair<uint8_t, uint16_t>>();
auto user_class = UserDefineClass<uint32_t>();

仕様

auto による型推論は、以下の場所で初期化子がある場合のみ使用可能である。
  • ブロックスコープでの変数宣言
  • 名前空間スコープでの変数宣言
  • for 文の初期化文部での変数宣言
  • if 文、 switch 文、 for 文、 while 文の条件部での変数宣言
  • new 式の型名指定部
  • クラス定義内での静的メンバ宣言

なんとなく変数の初期化で使用できるイメージだが、使用できないケースについてGeminiで確認した。
が、思考モードにしても結構適当言われたので無課金だとあんまり当てにならないな...
cpprefjpを適当でもだらだら見ていなかったら気づかんかったな
以下内容は一応整合性は確認した。

autoが使用できないケース
  • 関数引数
    確かに、あまり見たことない気がする。
    C++14でジェネリックラムダ、C++20で関数テンプレートの簡易定義というものが追加され使用できるようになっているらしい。
    詳細はまたいずれ...

  • 非静的メンバ変数
    言われてみると関数内、式の中でしか見てないな。
    static constまたはstatic constexprの場合は使用可能らしい。
    wnadbox

  • 関数の戻り値
    C++11の機能戻り値の型を後置する関数宣言構文 [N2541]で表現可能。

    auto func() -> int {
        return 0;
    }
    

    以前、標準ライブラリのtype_traitsを見ていた時に結構見かけた。
    ただ、自分で実装する時に使用するかといわれると...
    現状あんまり有効活用できるイメージがない

  • 配列宣言
    初期化子リストとしては使用可能らしい。一応コード例 wandbox
  • テンプレート引数
    c++17からは使用可能らしい 非型テンプレートパラメータのauto宣言 [P0127R2]