【C++】型の別名を付けるtypedefとusingの違いと使い方

目次

はじめに

C++で、unsigned long long や関数ポインタ void (*)(int) のように、型名が長くて複雑になることがあります。このような型を何度も記述するのは、コードを読みにくくし、typoの原因にもなります。

この問題を解決するのが「型の別名宣言(タイプエイリアシング)」です。既存の型に、より短く、より意味の分かりやすい別名を付けることで、コードの可読性と保守性を向上させることができます。

この記事では、型の別名を定義するための伝統的な typedef と、C++11で導入された、よりモダンで推奨される using の使い方を比較しながら解説します。


型の別名宣言のサンプルコード

このコードは、基本的な型、配列型、関数ポインタ型のそれぞれに対して、typedefusing の両方で別名を定義し、それらが同じように使えることを示します。

完成コード

#include <iostream>

// --- 1. 基本的な型 ---
// 伝統的な typedef
typedef unsigned int u_int;
// C++11以降の using
using UnsignedInt = unsigned int;

// --- 2. 配列型 ---
typedef int IntArray10[10];
using TenIntegers = int[10];

// --- 3. 関数ポインタ型 ---
typedef void (*LegacyFuncPtr)(int);
using ModernFuncPtr = void (*)(int);

// 関数ポインタに代入するためのサンプル関数
void sample_function(int n) {
    std::cout << "関数が値 " << n << " で呼び出されました。" << std::endl;
}

int main() {
    // 基本的な型のエイリアスを使用
    u_int var1 = 10;
    UnsignedInt var2 = 20;

    // 配列型のエイリアスを使用
    IntArray10 arr1 = {};
    arr1[0] = 100;
    
    // 関数ポインタ型のエイリアスを使用
    LegacyFuncPtr p1 = &sample_function;
    ModernFuncPtr p2 = &sample_function;
    
    p1(var1);
    p2(var2);

    return 0;
}

コードの解説

1. typedef による別名宣言

typedef は、C言語から引き継がれた伝統的な方法です。

typedef 既存の型 新しい型名;

構文が少し特殊で、通常の変数宣言の先頭に typedef を付けたような形になります。

  • typedef unsigned int u_int;: unsigned intu_int という別名を付けます。
  • typedef int IntArray10[10];: int[10](10個のintを持つ配列)という型に、IntArray10 という別名を付けます。
  • typedef void (*LegacyFuncPtr)(int);: void (*)(int)intを引数に取りvoidを返す関数へのポインタ)という型に、LegacyFuncPtr という別名を付けます。

2. using による別名宣言 (C++11)

using は、C++11で導入された、より直感的で高機能な別名宣言の方法です。

using 新しい型名 = 既存の型;

= を使った代入のような構文で、どの型がどの名前になるのかが非常に分かりやすくなっています。

  • using UnsignedInt = unsigned int;
  • using TenIntegers = int[10];
  • using ModernFuncPtr = void (*)(int);

using が推奨される理由

基本的な型では typedefusing に大きな違いはありませんが、テンプレートと組み合わせる際に using の方がはるかに強力で分かりやすいという利点があります(エイリアステンプレート)。

// using を使えば、テンプレートの別名宣言も簡単
template<typename T>
using StringMap = std::map<std::string, T>;

// std::map<std::string, int> の代わりに使える
StringMap<int> my_map; 

このため、現代のC++では、型の別名宣言には原則として using を使うことが推奨されます。


まとめ

今回は、C++で型の別名を付けるための typedefusing を解説しました。

  • typedef: C言語互換の伝統的な方法。
  • using (C++11): より直感的で高機能な、推奨される方法。

型の別名宣言は、複雑な型名を単純化し、コードの意図を明確にすることで、プログラム全体の可読性と保守性を向上させる重要なテクニックです。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次