I'm tyring to understand std::enable_if
and the benefits of using it over a static_assert / regular template specialitzation.
After reading around I found:
This is useful to hide signatures on compile time when a particular condition is not met, since in this case, the member enable_if::type will not be defined and attempting to compile using it should fail. http://www.cplusplus.com/reference/type_traits/enable_if/
My question then is: Why the compiler blames me by saying that class C is already declared?, when only one of the declaraions should be avaiable at a time.
class Interface{};
class Foo : public Interface{};
template <class T, typename = typename std::enable_if<std::is_base_of<Interface,T>::value>::type>
class C{
// Some custom implementation
}
template <class T, typename = typename std::enable_if<!std::is_base_of<Interface,T>::value>::type>
class C {
//Some fallback / default implementation
}
int main() {
C<Foo> myVariable;
}
Same behaviour in Godbolt: https://godbolt.org/z/cbfhG9q54
Thanks in advance!
You cannot overload class templates like you can function templates, buy you can partially specialize them (which you cannot do with function templates):
#include <ios>
#include <iostream>
#include <type_traits>
class Interface
{};
class Foo : public Interface
{};
template <class T, typename = void>
struct C
{
// Some default impl.
static constexpr bool is_default_impl{true};
};
template <class T>
struct C<T, std::enable_if_t<std::is_base_of_v<Interface, T>>>
{
// Some custom implementation.
static constexpr bool is_default_impl{false};
};
int main()
{
std::cout << std::boolalpha
<< C<int>::is_default_impl << " " // true
<< C<Foo>::is_default_impl; // false
}
Note that this examples requires C++17 for the variable template std::is_base_of_v
which is a short-hand constant the value
member of the std::is_base_of
trait, and C++14 for the alias template std::enable_if_t
, which aliases the type
member alias declaration of the std::enable_if
trait.