初心者なので,ググったりなんだりして template なコード見かけた際に
「何この文法は? 読めないんですけど??」
ってなることが割とあるので,調べたことをなんとなくメモしようかと.
template 引数名は省略可
以下の例で template 引数の名前( T, I )は全く使われてない.
こういうのは無くて良いらしい.
template< typename T > //←この名前 T は使われてない
void F(){ std::cout << "This is F<T>()\n"; }
template< int I > //←この名前 I は使われてない
void K(){ std::cout << "This is K<int>()\n"; }
↓
template< typename > //←名前が不要なら書かなくていい
void F(){ std::cout << "This is F<T>()\n"; }
template< int > //←名前が不要なら書かなくていい
void K(){ std::cout << "This is K<int>()\n"; }
「そしたら何故 template にしたし?」というと,目的は特殊化なのだろう.
//特定の型の場合は尊い文字列を表示する
template<>
void F<int>(){ std::cout << "This is F<int>() ; Cheetoh !\n"; }
//特定の値の場合は尊い文字列を表示する
template<>
void K<7>(){ std::cout << "This is K<7>() ; Toyger !\n"; }
template 引数が template とかいう
こういうやつ↓.
見た瞬間にめまいがする.自分で書く機会は永久に無さそう.
template< template<typename> typename T >
void G(){ /* ... */ }
どうやら
-
Gは関数テンプレートであって,その template 引数は型引数が1つ(T)であり……- この
Tに使える型というのは, template 引数が型引数1個なクラステンプレートなのですぞ
- この
……っていうような話である様子.
だから G() の実装内にはきっとこんなの↓が出現することになるのだと思われ.
template< template<typename> typename T >
void G()
{
T< std::string > T_Instance; //← T はこれがコンパイル通る型
}
なお,ここで T の template 引数に名前を付けてみたところで,それを G() 内で使えるわけではない とのことだ.
// X っていう名前を書いてみたけども……
template< template<typename X> typename T >
void G()
{
//コンパイルエラーが2つ出た(VS2019)
//C2065 'X': 定義されていない識別子です
//C3861 'X': 識別子が見つかりませんでした
std::cout << typeid(X).name(); //(※なんかてきとーに X を使おうとした記述)
}
template<auto>
stack overflow を何となく眺めてたら,唐突な auto が出てきた.
まぁ使う機会は無さそう.
//こんなものを書く場合……
template< typename T, T Val > //「非型パラメタValの型 を 型パラメタにしたい」とかいう
void F(){ std::cout << Val << std::endl; }
F<int,7>(); //使用例
F<char,'c'>(); //使用例
/* --- ↓ --- */
//こう書ける,という話みたい
template< auto Val >
void F(){ std::cout << Val << std::endl; }
F<7>(); //使用例
F<'c'>(); //使用例
試行MEMO :
//名称の省略と特殊化
template< auto > void F2(){ std::cout << "Cat\n"; }
template<> void F2<100>(){ std::cout << "Wild Cat!!\n"; }
//Fold とかいうのと組み合わせてみる
template< auto ...Vals >
void F3()
{ ( (std::cout << Vals << " ") , ... ); }
F3<'c', 40, -7, '\n'>(); //使用例
以降未定
(今後,何か増えたら追記しようかと)