Pregunta

Can I mix SFINAE for expressions and decltype auto?

template<class T>
auto function() -> decltype(typename trait<T>::test(), auto) {
  return [](){ return T(); };
}
¿Fue útil?

Solución

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(); };
}

Otros consejos

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top