SFINAEの動作に納得がいかない
と思ったこの頃。復習がてらにSFINAEを用いたコードを書いたのだが
template<class std_class> auto size(std_class c)->decltype(c.size(),bool()){return true;} auto size(...)->bool{return false;} int main() { std::cout<<std::boolalpha<<size(std::string())<<std::endl; // true std::cout<<size(int())<<std::endl; // false }
これならば期待通りにSFINAEが動いてくれていて気持ちが良い。
しかし、以下のようにテンプレートパラメータを加えただけで、SFINAEが期待通りの動作をしなくなってしまった。
template<class std_class,class> // here auto size(std_class c)->decltype(c.size(),bool()){return true;} auto size(...)->bool{return false;} #include<string> #include<iostream> int main() { std::cout<<std::boolalpha<<size(std::string())<<std::endl; // false std::cout<<size(int())<<std::endl; // false }
まあ、使いもしないテンプレートパラメータを書くのは、そもそも有りえないというか、意味の無い行為だとは思うのだけれども、テンプレートパラメータを加えただけでSFINAEがオーバーロード候補から除外してしまうのは、なんだか動作に納得ができない。
構文解析の段階でしょうがなく、そういう仕様になるのかもしれないけど、気持ちの悪い動作に感じてしまう。
やはり納得するためには、規格所を基に厳密に知らなければならないなと思った。
それか...どこか理解しているつもりなだけで意味的に全く間違っている事をしてしまっているのだろうか。
もし何かこれに対してご教授してくださる方がいらっしゃいましたら、是非コメントの方によろしくお願いいたします。
#追記
cpprefjpのSFINAEの項目を見逃していた。
注釈:型推論は次の理由で失敗する可能性がある: 異なる長さの複数パラメータパックを含んでいるパック拡張をインスタンス化することを試みること。
任意の式によるSFINAE - cpprefjp C++日本語リファレンス
これに該当する事例なのだろうか。