Type alias, alias template (since C++11)
型エイリアスは、以前に定義された型を参照する名前です(
typedef
と同様)。
エイリアステンプレートは、型のファミリーを参照する名前です。
目次 |
構文
エイリアス宣言は以下の構文を持つ 宣言 です:
using
identifier
attr
(optional)
=
type-id
;
|
(1) | ||||||||
template
<
template-parameter-list
>
|
(2) | ||||||||
template
<
template-parameter-list
>
requires
constraint
|
(3) | (C++20以降) | |||||||
| attr | - | 任意の数の 属性 のオプションのシーケンス |
| identifier | - | この宣言によって導入される名前。これは型名 (1) またはテンプレート名 (2) となる |
| template-parameter-list | - | テンプレートパラメータリスト 。 テンプレート宣言 と同様 |
| constraint | - | このエイリアステンプレートが受け入れるテンプレートパラメータを制限する 制約式 |
| type-id | - | 抽象宣言子またはその他の有効な type-id ( type-id で説明されているように、新しい型を導入する可能性がある)。 type-id は直接または間接的に identifier を参照できない。識別子の 宣言点 は 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 |
キーワード
例
#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
宣言
|
型の別名を作成する |
| 名前空間エイリアス | 既存の名前空間の別名を作成する |