汎用エイリアス宣言の提案
P0945R0: p0945r0: Generalizing alias declarations
提案に誤りが有りすぎる。
C++のドラフトに入る見込みが高そうな提案に、汎用エイリアス宣言がある。
C++では、名前に別名をつけることがよく行われている。
型はtypedef指定子やエイリアス宣言によって別名を付けられる。
typedef int type ;
using type = int ;
関数は転送関数を書くことにより、実質別名を付けられる。
int f( int x ) ;
int g( int x )
{
return f(x) ;
}
ただし、値は完璧に転送できないし、関数のアドレスも異なるものになってしまう。
変数はリファレンスで別名を付けられる。
int x = 0 ;
int & y = x ;
非staticデータメンバーはストレージを消費せずに別名をつけることができない
enumeratorはconstexpr inline変数によって別名を付けられる。
enum { value } ;
constexpr inline auto flag = value ;
ただしinline変数は名前空間スコープでしか使えない。
名前空間は名前空間エイリアスにより別名を付けられる。
namespace a { }
namespace b = a ;
型テンプレートはエイリアステンプレートで別名を定義できるが、デフォルトテンプレートパラメーターまで再現しなければならない。
template < typename T, typename Allocator = std::allocator<T> >
using vec = std::vector<T, Allocator> ;
ただし、この別名は別のテンプレートとして解釈されてしまう。
コンセプトは別のコンセプトを定義すれば別名を付けられる。
template < typename T >
concept newConcept = oldConcept<T> ;
名前の種類によって別名を宣言する文法が異なるし、単なる別名以上の意味を持つものもある。
この提案では、別名の宣言をエイリアス宣言に集約する。
using alias_name = name ;
型は今までどおりだが、その他
型、今までどおり
using type = int ;
// 関数
int f(int) ;
using g = f ;
// 変数
int x = 0 ;
using y = x ;
// 非staticデータメンバー
template < typename Type, typename Value >
struct map_node : std::pair<Type, Value>
{
using std::pair<Type, Value>::pair ;
using key = first ;
using value = second ;
} ;
[]{
map_node< int, std::string> n( 123, "123") ;
n.key ;
n.value ;
} ;
// enum
enum { value } ;
using flag = value ;
// 名前空間
namespace a ;
using b = a ;
// 型テンプレート
using vec = std::vector ;
vec<int> v ;
// コンセプト
using newConcept = oldConcept ;
だいぶすっきりする。とくに非staticデータメンバーがよい。