Namespaces
Variants

Type alias, alias template (since C++11)

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

型エイリアスは、以前に定義された型を参照する名前です( typedef と同様)。

エイリアステンプレートは、型のファミリーを参照する名前です。

目次

構文

エイリアス宣言は以下の構文を持つ 宣言 です:

using identifier attr  (optional) = type-id ; (1)
template < template-parameter-list >

using identifier attr  (optional) = type-id ;

(2)
template < template-parameter-list > requires constraint

using identifier attr  (optional) = type-id ;

(3) (C++20以降)
attr - 任意の数の 属性 のオプションのシーケンス
identifier - この宣言によって導入される名前。これは型名 (1) またはテンプレート名 (2) となる
template-parameter-list - テンプレートパラメータリスト テンプレート宣言 と同様
constraint - このエイリアステンプレートが受け入れるテンプレートパラメータを制限する 制約式
type-id - 抽象宣言子またはその他の有効な type-id type-id で説明されているように、新しい型を導入する可能性がある)。 type-id は直接または間接的に identifier を参照できない。識別子の 宣言点 type-id に続くセミコロンであることに注意。

説明

1) 型エイリアス宣言は、 type-id で示される型のシノニムとして使用できる名前を導入します。これは新しい型を導入するものではなく、既存の型名の意味を変更することもできません。型エイリアス宣言と typedef 宣言の間に違いはありません。この宣言はブロックスコープ、クラススコープ、または名前空間スコープで現れることがあります。
2) エイリアステンプレートは、特殊化された際に、エイリアステンプレートのテンプレート引数を type-id 内のテンプレートパラメータに置換した結果と等価となるテンプレートです。
template<class T>
struct Alloc {};
template<class T>
using Vec = vector<T, Alloc<T>>; // type-id is vector<T, Alloc<T>>
Vec<int> v; // Vec<int> is the same as vector<int, Alloc<int>>

エイリアステンプレートの特殊化結果が依存 template-id である場合、後続の置換はそのtemplate-idに適用されます:

template<typename...>
using void_t = void;
template<typename T>
void_t<typename T::foo> f();
f<int>(); // error, int does not have a nested type foo

エイリアステンプレートを特殊化した際に生成される型が、直接的または間接的に自身の型を使用することは許可されていません:

template<class T>
struct A;
template<class T>
using B = typename A<T>::U; // type-id is A<T>::U
template<class T>
struct A { typedef B<T> U; };
B<short> b; // error: B<short> uses its own type via A<short>::U

エイリアステンプレートは、テンプレートテンプレートパラメータを推定する際の テンプレート引数推定 によって決して推定されることはありません。

エイリアステンプレートを 部分的 または 明示的に特殊化 することはできません。

任意のテンプレート宣言と同様に、エイリアステンプレートはクラススコープまたは名前空間スコープでのみ宣言できます。

ラムダ式 がエイリアステンプレート宣言内に現れる場合、その型はラムダ式が非依存であっても、テンプレートのインスタンス化ごとに異なる。

template<class T>
using A = decltype([] {}); // A<int> and A<char> refer to different closure types
(C++20以降)

注記

機能テストマクロ 規格 機能
__cpp_alias_templates 200704L (C++11) Alias templates

キーワード

using

#include <iostream>
#include <string>
#include <type_traits>
#include <typeinfo>
// 型エイリアス、以下と同一
// typedef std::ios_base::fmtflags flags;
using flags = std::ios_base::fmtflags;
// 名前 'flags' は型を表す:
flags fl = std::ios_base::dec;
// 型エイリアス、以下と同一
// typedef void (*func)(int, int);
using func = void (*) (int, int);
// 名前 'func' は関数ポインタを表す:
void example(int, int) {}
func f = example;
// エイリアステンプレート
template<class T>
using ptr = T*;
// 名前 'ptr<T>' はTへのポインタのエイリアス
ptr<int> x;
// テンプレートパラメータを隠すための型エイリアス
template<class CharT>
using mystring = std::basic_string<CharT, std::char_traits<CharT>>;
mystring<char> str;
// 型エイリアスはメンバーtypedef名を導入できる
template<typename T>
struct Container { using value_type = T; };
// ジェネリックプログラミングで使用可能
template<typename ContainerT>
void info(const ContainerT& c)
{
    typename ContainerT::value_type T;
    std::cout << "ContainerT is `" << typeid(decltype(c)).name() << "`\n"
                 "value_type is `" << typeid(T).name() << "`\n";
}
// std::enable_ifの構文を簡略化する型エイリアス
template<typename T>
using Invoke = typename T::type;
template<typename Condition>
using EnableIf = Invoke<std::enable_if<Condition::value>>;
template<typename T, typename = EnableIf<std::is_polymorphic<T>>>
int fpoly_only(T) { return 1; }
struct S { virtual ~S() {} };
int main()
{
    Container<int> c;
    info(c); // この関数内ではContainer::value_typeはintとなる
//  fpoly_only(c); // エラー: enable_ifがこれを禁止
    S s;
    fpoly_only(s); // OK: enable_ifがこれを許可
}

出力例:

ContainerT is `struct Container<int>`
value_type is `int`

不具合報告

以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。

DR Applied to Behavior as published Correct behavior
CWG 1558 C++11 エイリアス特殊化における未使用引数が
置換に参加するかどうかが規定されていなかった
置換
が実行される

関連項目

typedef 宣言 型の別名を作成する
名前空間エイリアス 既存の名前空間の別名を作成する