std::enable_if
STD::启用[医]如果
Defined in header | | |
---|---|---|
template< bool B, class T = void > struct enable_if; | | (since C++11) |
如果B
是true
,,,std::enable_if
具有一个公共成员类型type
,等于T
否则,就没有成员tyUIDEf。
这个元功能是一种方便的方式来利用。SFINAE有条件地从过载分辨率根据类型特征,为不同类型性状提供单独的功能过载和专门化。std::enable_if
可用作附加函数参数%28,不适用于运算符重载%29、返回类型%28不适用于构造函数和析构函数%29,也可用作类模板或函数模板参数。
成员类型
Type | Definition |
---|---|
type | either T or no such member, depending on the value of B |
帮助者类型
template< bool B, class T = void > using enable_if_t = typename enable_if::type; | | (since C++14) |
---|
可能的实施
模板<bool B,类T=void>结构启用[医]if{};模板<class T>结构启用[医]如果<true,则T>{tydurif T类型;};
*。
注记
一个常见的错误是声明两个仅在默认模板参数中不同的函数模板。这是非法的,因为默认模板参数不是函数模板%27签名的一部分,并且声明两个具有相同签名的不同函数模板是非法的。
二次
struct T {
enum { int_t,float_t } m_type;
template <typename Integer,
typename = std::enable_if_t<std::is_integral<Integer>::value>
>
T(Integer) : m_type(int_t) {}
template <typename Floating,
typename = std::enable_if_t<std::is_floating_point<Floating>::value>
>
T(Floating) : m_type(float_t) {} // error: cannot overload
};
二次
例
二次
#include <type_traits>
#include <iostream>
#include <string>
namespace detail { struct inplace_t{}; }
void* operator new(std::size_t, void* p, detail::inplace_t) {
return p;
}
// #1, enabled via the return type
template<class T,class... Args>
typename std::enable_if<std::is_trivially_constructible<T,Args&&...>::value>::type
construct(T* t,Args&&... args)
{
std::cout << "constructing trivially constructible T\n";
}
// #2
template<class T, class... Args>
std::enable_if_t<!std::is_trivially_constructible<T,Args&&...>::value> //Using helper type
construct(T* t,Args&&... args)
{
std::cout << "constructing non-trivially constructible T\n";
new(t, detail::inplace_t{}) T(args...
}
// #3, enabled via a parameter
template<class T>
void destroy(T* t,
typename std::enable_if<std::is_trivially_destructible<T>::value>::type* = 0)
{
std::cout << "destroying trivially destructible T\n";
}
// #4, enabled via a template parameter
template<class T,
typename std::enable_if<
!std::is_trivially_destructible<T>{} &&
(std::is_class<T>{} || std::is_union<T>{}),
int>::type = 0>
void destroy(T* t)
{
std::cout << "destroying non-trivially destructible T\n";
t->~T(
}
// #5, enabled via a template parameter
template<class T,
typename = std::enable_if_t<std::is_array<T>::value> >
void destroy(T* t) // note, function signature is unmodified
{
for(std::size_t i = 0; i < std::extent<T>::value; ++i) {
destroy((*t)[i]
}
}
/*
template<class T,
typename = std::enable_if_t<std::is_void<T>::value> >
void destroy(T* t){} // error: has the same signature with #5
*/
// the partial specialization of A is enabled via a template parameter
template<class T, class Enable = void>
class A {}; // primary template
template<class T>
class A<T, typename std::enable_if<std::is_floating_point<T>::value>::type> {
}; // specialization for floating point types
int main()
{
std::aligned_union_t<0,int,std::string> u;
construct(reinterpret_cast<int*>(&u)
destroy(reinterpret_cast<int*>(&u)
construct(reinterpret_cast<std::string*>(&u),"Hello"
destroy(reinterpret_cast<std::string*>(&u)
A<int> a1; // OK, matches the primary template
A<double> a2; // OK, matches the partial specialization
}
二次
产出:
二次
constructing trivially constructible T
destroying trivially destructible T
constructing non-trivially constructible T
destroying non-trivially destructible T
二次
另见
void_t (C++17) | void variadic alias template (alias template) |
---|
- 静态[医]断言
- SFINAE
© cppreference.com
在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。