Reputation: 7415
Can I mix SFINAE for expressions and decltype auto?
template<class T>
auto function() -> decltype(typename trait<T>::test(), auto) {
return [](){ return T(); };
}
Upvotes: 2
Views: 286
Reputation: 171303
No, I don't think you can.
The grammar doesn't allow it:
decltype-specifier:
decltype
(
expression)
decltype
(
auto
)
decltype(expr, auto)
is not a valid decltype-specifier, whereas decltype(auto)
is and it has special meaning as a placeholder type. The wording is quite specific:
The type of a variable declared using
auto
ordecltype(auto)
is deduced from its initializer [...]auto
ordecltype(auto)
shall appear as one of the decl-specifiers in the decl-specifier-seq and the decl-specifier-seq shall be followed by one or more init-declarators, each of which shall have a non-empty initializer.
In C++17 Concepts Lite should make such SFINAE hacks unnecessary anyway, so we won't have to rely on them forever. You could modify your example to put the SFINAE constraint in a default template argument:
template<class T, class Requires = decltype(typename trait<T>::test())>
auto function() -> decltype(auto) {
return [](){ return T(); };
}
Upvotes: 2
Reputation: 71989
You can use the default template argument SFINAE with function return type deduction though.
template<class T, class = decltype(typename trait<T>::test())>
auto function() {
return [](){ return T(); };
}
The downside is that you don't have the parameter names available.
Upvotes: 1