式に SFINAE と decltype auto を混在させることはできますか?
template<class T>
auto function() -> decltype(typename trait<T>::test(), auto) {
return [](){ return T(); };
}
いいえ、できないと思います。
文法はそれを許可しません:
decltype-specifier:
decltype
(
式)
decltype
(
auto
)
decltype(expr, auto)
は有効なdecltype-specifierではありませんが、これdecltype(auto)
はプレースホルダー型として特別な意味を持ちます。言葉遣いは非常に具体的です。
宣言された変数の型、
auto
またはdecltype(auto)
初期化子から推定される変数 [...]auto
またはdecltype(auto)
decl-specifier-seq の decl-specifiers の 1 つとして表示され、decl-specifier-seq の後に 1 つ以上の init が続くものとします-宣言子。それぞれが空でない初期化子を持つ必要があります。
C++17 の Concepts Lite では、とにかくそのような SFINAE ハックを不要にする必要があるため、それらに永遠に依存する必要はありません。例を変更して、SFINAE 制約をデフォルトのテンプレート引数に入れることができます。
template<class T, class Requires = decltype(typename trait<T>::test())>
auto function() -> decltype(auto) {
return [](){ return T(); };
}
ただし、関数の戻り値の型推論でデフォルトのテンプレート引数 SFINAE を使用できます。
template<class T, class = decltype(typename trait<T>::test())>
auto function() {
return [](){ return T(); };
}
欠点は、利用可能なパラメーター名がないことです。