c++ 中std::enable_if

参考:
https://blog.csdn.net/kpengk/article/details/119979733

enable_if

定义

// STRUCT TEMPLATE enable_if
template <bool _Test, class _Ty = void>
struct enable_if {}; // no member "type" when !_Test

template <class _Ty>
struct enable_if<true, _Ty> { // type is _Ty for _Test
    using type = _Ty;
};

只有_Test为true时,类成员才有定义。
std::enable_if可以用作函数参数、返回类型或类模板或函数模板参数,以有条件地从重载中删除函数或类。

enable_if_t

enable_if_t是一个别名,其定义如下:

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

因此,如果能够使用enable_if_t,使用它更方便。

一、作为函数参数

template<typename T>
struct Check1
{
    //如果T的类型是int,则定义函数 int read(void* = nullptr)
	template<typename U = T>
	U read(typename std::enable_if_t<std::is_same_v<U, int> >* = nullptr) {
		return 42;
	}
    
    //如果T的类型是double,则定义函数 double read(void* = nullptr)
	template<typename U = T>
	U read(typename std::enable_if_t<std::is_same_v<U, double> >* = nullptr) {
		return 3.14;
	}
};

二、作为模板参数

template<typename T>
struct Check2
{
    //如果T的类型是int,则定义函数 int read()
	template<typename U = T, typename std::enable_if_t<std::is_same_v<U, int>, int> = 0>
	U read() {
		return 42;
	}
    
    //如果T的类型是double,则定义函数 double read()
	template<typename U = T, typename std::enable_if_t<std::is_same_v<U, double>, int> = 0>
	U read() {
		return 3.14;
	}
};

三、作为返回值类型

template<typename T>
struct Check3
{
    //如果T的类型是int,则定义函数 int read()
	template<typename U = T>
	typename std::enable_if_t<std::is_same_v<U, int>, U> read() {
		return 42;
	}

    //如果T的类型是double,则定义函数 double read()
	template<typename U = T>
	typename std::enable_if_t<std::is_same_v<U, double>, U> read() {
		return 3.14;
	}
};

四、类型偏特化

// T是其它类型
template<typename T, typename = void>
struct zoo;

// 如果T是浮点类型
template<typename T>
struct zoo<T, std::enable_if_t<std::is_integral_v<T>>>
{
};

五、concepts
C++20中利用concepts可以简化编写方式:

#ifdef __cpp_lib_concepts
#include <concepts>
#endif

// 如果T是整数类型
template<std::integral T>
void display_concepts_1(T num)
{
}

// 如果T是整数类型
void display_concepts(std::integral auto num)
{
}

// 如果T是浮点数类型
void display_concepts(std::floating_point auto num)
{
}

// 如果T是整数类型
template<typename T, typename std::enable_if_t<std::is_integral_v<T>>* = nullptr>
void display_1(T num)
{
}

// 如果T是整数类型
template<typename T>
void display(typename std::enable_if_t<std::is_integral_v<T>>* = nullptr)
{
}

// 如果T是浮点数类型
template<typename T>
void display(typename std::enable_if_t<std::is_floating_point_v<T>>* = nullptr)
{
}

posted @ 2025-04-16 19:02  老禾的账本  阅读(70)  评论(0)    收藏  举报