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
成员别名声明设置了别名。
我很想了解 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
成员别名声明设置了别名。