std::enable_if
| Defined in header <type_traits> |  |  | 
|---|---|---|
| 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<B,T>::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。
本文档系腾讯云开发者社区成员共同维护,如有问题请联系 cloudcommunity@tencent.com

