std::enable_if 选择 class 专业

std::enable_if to choose a class specialitzation

我很想了解 std::enable_if 以及在 static_assert / regular template specialitzation.

上使用它的好处

看完之后我发现:

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/

然后我的问题是:为什么编译器指责我说 class C 已经被声明了?,而一次只有一个声明可用。

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

Godbolt 中的相同行为:https://godbolt.org/z/cbfhG9q54

提前致谢!

你不能重载 class 模板,就像你可以使用模板一样,买你可以部分专业化它们(你不能使用函数模板):

#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
}

请注意,此示例需要 C++17 的变量模板 std::is_base_of_v,它是 std::is_base_of 特性的 value 成员的简写常量,以及 C++ 14 用于别名模板 std::enable_if_t,它为 std::enable_if 特征的 type 成员别名声明设置了别名。