gnzlbg
gnzlbg

Reputation: 7415

SFINAE for expressions and decltype(auto)

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

Answers (2)

Jonathan Wakely
Jonathan Wakely

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 or decltype(auto) is deduced from its initializer [...] auto or decltype(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

Sebastian Redl
Sebastian Redl

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

Related Questions