std::enable_if && std::enable_if_t && std::is_same

std::is_same

<type_traits>头文件中提供了C++ STL的std::is_same模板。 C++ STL的std::is_same模板用于检查类型A是否与类型B相同。如果两者相同,则返回布尔值true,否则返回false。

模板类型

template <class A, class B>
struct is_same
 
template <class A, class B>
inline constexpr 
       bool is_same_v
         = is_same<A, B>::value

用法

std::is_same<A, B>::value

实例

#include <iostream>
#include <type_traits>
#include <cstdint>
 
int main()
{
    //使bool型变量按照false、true的格式输出。
    //如不使用该标识符,那么结果会按照1、0的格式输出。
    std::cout << std::boolalpha;
 
    // usually true if 'int' is 32 bit
    std::cout << std::is_same<int, std::int32_t>::value << ' '; // ~ true
    std::cout << std::is_same<int, std::int64_t>::value << ' '; // ~ false
 
    // same tests as above, except using C++17's `std::is_same_v<T, U>` format
    std::cout << std::is_same_v<int, std::int32_t> << ' ';  // ~ true
    std::cout << std::is_same_v<int, std::int64_t> << '\n'; // ~ false
 
    // compare the types of a couple variables
    long double num1 = 1.0;
    long double num2 = 2.0;
    std::cout << std::is_same_v<decltype(num1), decltype(num2)> << '\n'; // true
 
    // 'float' is never an integral type
    std::cout << std::is_same<float, std::int32_t>::value << '\n'; // false
 
    // 'int' is implicitly 'signed'
    std::cout << std::is_same<int, int>::value << ' ';          // true
    std::cout << std::is_same<int, unsigned int>::value << ' '; // false
    std::cout << std::is_same<int, signed int>::value << '\n';  // true
 
    system("pause");
    return 0;
 
}

 std::enable_if

模板类型

template<bool B, class T = void>
struct enable_if {};
 
template<class T>
struct enable_if<true, T> { typedef T type; };

用法一:类型偏特化

在使用模板编程时,经常会用到根据模板参数的某些特性进行不同类型的选择,或者在编译时校验模板参数的某些特性。

template <typename T, typename Enable=void>
struct check;

template <typename T>
struct check<T, typename std::enable_if<T::value, T>::type> {
  static constexpr bool value = T::value;
};

上述的 check 只希望选择 value==true 的 T,否则就报编译时错误。如果想给用户更友好的提示,可以提供结构体的原型定义,并在其中进行 static_assert 的静态检查,给出更明确的字符串说明。

用法二:控制函数返回类型

对于模板函数,有时希望根据不同的模板参数返回不同类型的值,进而给函数模板也赋予类型模板特化的性质。典型的例子可以参看 tuple 的获取第 k 个元素的 get 函数:

template <std::size_t k, class T, class... Ts>
typename std::enable_if<k==0, typename element_type_holder<0, T, Ts...>::type&>::type
get(tuple<T, Ts...> &t) {
  return t.tail;
}

template <std::size_t k, class T, class... Ts>
typename std::enable_if<k!=0, typename element_type_holder<k, T, Ts...>::type&>::type
get(tuple<T, Ts...> &t) {
  tuple<Ts...> &base = t;
  return get<k-1>(base);
}

由于函数模板不能偏特化,通过 enable_if 便可以根据 k 值的不同情况选择调用哪个 get,进而实现函数模板的多态。

用法三:校验函数模板参数类型

有时定义的模板函数,只希望特定的类型可以调用,参考 cppreference 官网示例,很好的说明了如何限制只有整型可以调用的函数定义:

template <typename T>
typename std::enable_if<std::is_integral<T>::value, bool>::type
is_odd(T t) {
  return bool(t%2);
}

template <typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
bool is_even(T t) {
  return !is_odd(t);
}

一个通过返回值,一个通过默认模板参数,都可以实现校验模板参数是整型的功能。

std::enable_if_t

模板类型

template <bool _Test, class _Ty = void>
using enable_if_t = typename enable_if<_Test, _Ty>::type;

和std::enable_if的功能类似。

用法

class B {};
class C {};

template <typename T, typename std::enable_if<std::is_same<T, B>::value, T>::type* = nullptr>
void HandleType(T type);


template <typename T, typename std::enable_if_t<std::is_same<T, B>::value>* = nullptr>
void HandleType(T type);

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值