名前空間
変種
操作

型エイリアス、エイリアステンプレート (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

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

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

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

目次

[編集] 構文

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

using identifier attr (省略可能) = type-id ; (1)
template < template-parameter-list >

using identifier attr (省略可能) = type-id ;

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

using identifier attr (省略可能) = type-id ;

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

[編集] 解説

1) 型エイリアス宣言は、型IDによって示される型の同義語として使用できる名前を導入する。新しい型を導入するものではなく、既存の型名の意味を変更することはできない。型エイリアス宣言とtypedef宣言の間に違いはない。この宣言は、ブロックスコープ、クラススコープ、または名前空間スコープに現れることができる。
2) エイリアステンプレートは、特殊化されたときに、エイリアステンプレートのテンプレート引数を型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>>

エイリアステンプレートを特殊化した結果が依存するテンプレートIDである場合、後続の置換はそのテンプレート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) エイリアステンプレート

[編集] キーワード

using

[編集]

#include <iostream>
#include <string>
#include <type_traits>
#include <typeinfo>
 
// type alias, identical to
// typedef std::ios_base::fmtflags flags;
using flags = std::ios_base::fmtflags;
// the name 'flags' now denotes a type:
flags fl = std::ios_base::dec;
 
// type alias, identical to
// typedef void (*func)(int, int);
using func = void (*) (int, int);
 
// the name 'func' now denotes a pointer to function:
void example(int, int) {}
func f = example;
 
// alias template
template<class T>
using ptr = T*;
// the name 'ptr<T>' is now an alias for pointer to T
ptr<int> x;
 
// type alias used to hide a template parameter
template<class CharT>
using mystring = std::basic_string<CharT, std::char_traits<CharT>>;
 
mystring<char> str;
 
// type alias can introduce a member typedef name
template<typename T>
struct Container { using value_type = T; };
 
// which can be used in generic programming
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";
}
 
// type alias used to simplify the syntax of 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 will be int in this function
//  fpoly_only(c); // error: enable_if prohibits this
    S s;
    fpoly_only(s); // okay: enable_if allows this
}

実行結果の例

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

[編集] 欠陥報告

以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。

DR 適用対象 公開された動作 正しい動作
CWG 1558 C++11 エイリアス特殊化における未使用引数が
置換に参加するかどうかが指定されていなかった
置換
が実行される

[編集] 関連項目

typedef宣言 型の同義語を作成する[編集]
名前空間エイリアス 既存の名前空間のエイリアスを作成する[編集]
English 日本語 中文(简体) 中文(繁體)