首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

std::enable_if

Defined in header <type_traits>

template< bool B, class T = void > struct enable_if;

(since C++11)

如果Btrue,,,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签名的一部分,并且声明两个具有相同签名的不同函数模板是非法的。

二次

代码语言:javascript
复制
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
};

二次

二次

代码语言:javascript
复制
#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
}

二次

产出:

二次

代码语言:javascript
复制
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
代码语言:txt
复制
 © cppreference.com

在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。

扫码关注腾讯云开发者

领取腾讯云代金券