在线文档教程
C++
应用 | Utilities

std::enable_if

STD::启用[医]如果

Defined in header
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,也可用作类模板或函数模板参数。

成员类型

TypeDefinition
typeeither 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。

http://en.cppreference.com/w/cpp/type/Enable[医]如果