本の虫

著者:江添亮
ブログ: http://cpplover.blogspot.jp/
メール: boostcpp@gmail.com
Twitter: https://twitter.com/EzoeRyou
GitHub: https://github.com/EzoeRyou

アマゾンの江添のほしい物リストを著者に送るとブログ記事のネタになる

筆者にブログのネタになる品物を直接送りたい場合、住所をメールで質問してください。

汎用エイリアス宣言の提案

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データメンバーがよい。