joaocandre
joaocandre

Reputation: 1745

Different member function definition according to compile-time condition

As per this answer, I've been using

template <typename T,
          typename = typename enable_if<bool_verfier<T>()>::type> >
classMember(const T& arg);

As the function signature for several class members, where bool_verifier<T>() is a templated function that asserts that a particular class T fulfills certain requirements, with return type constexpr bool. This ensures a particular overload of classMember(const T& arg) is only used for particular argument types, but it is not possible to do this when there are multiple overloads with the same prototype/argument signature, because the compiler won't allow it:

// ...
template <typename T, typename = typename enable_if<bool_verfier<T>()>::type> >
classMember(const T& arg);
template <typename T,  typename = typename enable_if<!(bool_verfier<T>())>::type>>
classMember(const T& arg);
// ...

which causes the following compilation error:

 ‘template<class T, class> void myClass::classMember<T>(const T&)’
 cannot be overloaded with
‘template<class T, class> void std::myClass<T>::classMember(const T&)’

If I need classMember to have different definitions according to whether or not bool_verifier<T>() returns true, what would be the correct syntax/member declaration? Alternatively, is there a way to call bool_verifier<T> from an #if precompiler conditional statement?

Upvotes: 0

Views: 71

Answers (1)

Vittorio Romeo
Vittorio Romeo

Reputation: 93294

Alternatively, is there a way to call bool_verifier<T> from an #if precompiler conditional statement?

Nope. The preprocessor runs before anything else, and doesn't have knowledge of C++ at all.


You probably need to disambiguate between the two overloads with an extra template parameter (or by changing where enable_if appears), as default template parameter values are not part of the signature. The following works for me:

struct foo
{
     template <typename T, typename = std::enable_if_t<bool_verifier<T>{}>> 
     void a();

     template <typename T, typename = std::enable_if_t<!bool_verifier<T>{}>, typename = void> 
     void a();
};

live godbolt.org link

Upvotes: 2

Related Questions