人生初心者の雑記

すべてにおいてド素人な人がいろんなことを書くよ

sfinaeのenabler 1/2

sfinaeのenablerについて疑問を持ちました

 

そのまえに、ど素人の俺がtemplateのデフォルト実引数について「へー面白いなー」と思ったことをかくよ。

テンプレートを書くときはこんな風にするよねー

template<class T,class U,int I>class Foo{};

でこの<>の中身の文法が、規格には「type-parameter」と「parameter-declaration」って書いてる。後者のほうは非型テンプレート引数の宣言だね

parameter-declarationってのは関数宣言の仮引数の宣言ルールでもある(まぁテンプレートの方はちょっと制約があるよ。完璧には知らんけど、型の制約があったり、コンパイル時に決まるものしか実引数に渡せないとか)

そんでー、よくsfinaeの例で使われる、

typename enable_if<(ry *& = enabler

てあるじゃん

これなんで識別子省略してもいいのかなーって思ったんだけど、上に書いた「parameter-declaration」の件を考えると、なんとなく通る理由がわかったよ

だって関数宣言って int func(int); とか省略するじゃん。あわよくばデフォルト引数を int func(int = 10);って書いたりできるからね。

 

それについてこんなクラスで確認してみた

 

///////////////////////コード始まり

template <class T,int = 8 >
struct Omission{
    Omission(){ std::cout << "Omission t" << std::endl; }
};

template<class T,int L>
struct Omission<T*,L>{
    Omission(){ std::cout << "Omission t* "<< L<< std::endl; }
};

 

////////////////////コード終わり

 

たとえばOmission<int*>()とかで部分特殊化の方を使うと、L にはデフォルト実引数で指定した8が入ってたことがわかった

関数のデフォルト実引数と同じような挙動をして面白いなーと思ったのでしたまる