Reputation: 7709
Suppose you attempt to do the following:
template</* args */>
typename std::enable_if< /*conditional*/ , /*type*/ >::type
static auto hope( /*args*/) -> decltype( /*return expr*/ )
{
}
Is it possible to combine conditional inclusion/overloading (std::enable_if
) with trailing-return-type (auto ... -> decltype()
)?
I would not be interesting in solutions using the preprocessor. I can always do things like
#define RET(t) --> decltype(t) { return t; }
and extend it to take also the whole conditional. Instead I am interested if the language supports it without using another trait for the return type, i.e. ReturnType<A,B>::type_t
or whatever is used in the function body.
Upvotes: 1
Views: 2356
Reputation: 131799
The trailing-return-type isn't much different from the normal return type, except that it's specified after the parameter list and cv-/ref-qualifiers. Also, it doesn't necessarily need decltype
, a normal type is fine too:
auto answer() -> int{ return 42; }
So by now you should see what the answer to your question is:
template<class T>
using Apply = typename T::type; // I don't like to spell this out
template</* args */>
static auto hope( /*args*/)
-> Apply<std::enable_if</* condition */, decltype( /*return expr*/ )>>
{
}
Though I personally prefer using just decltype
and expression SFINAE, as long as the condition can be expressed as an expression (e.g., can you invoke a function on an object of a certain type):
template<class T>
static auto hope(T const& arg)
-> decltype(arg.foo(), void())
{
// ...
}
Upvotes: 11
Reputation: 208363
I can only assume that your original pseudo code is a function template, or otherwise SFINAE would not work altogether. Now if it is a template function, you can use an extra template argument that is defaulted and use SFINAE on that argument:
template <typename T, typename _ = typename std::enable_if< trait<T>::value >::type >
static auto function( T arg ) -> decltype( expression ) {
// ...
}
I prefer this as it limits the use of SFINAE to the template
clause and leaves a cleaner function signature. This is one of my favorite under-the-radar new features of C++11.
Upvotes: 2