#include <iostream>
#include <type_traits>
using namespace std;
template<typename T1, typename T2>
struct IsSameT: std::false_type{};
template<typename T>
struct IsSameT<T, T>: std::true_type{};
template<typename T1, typename T2>
constexpr bool IsSame = IsSameT<T1, T2>::value;
void Test(){
std::cout<<boolalpha;
std::cout<<IsSame<int,int><<std::endl;
}
// 基于SFINAE类型萃取
// 用SFINAE排除某些重载函数
template<typename T>
struct IsDefaultConstructibleT{
private:
// 这里模板参数不能是T,只能由T进行传递,否则编译报:declaration of template parameter 'T' shadows template parameter
// 函数模板test根据U若无法构造,则不报错会(SFINAE)调用下面test模板
template<typename U, typename=decltype(U())>
static char test(void*);
template<typename>
static long test(...);
public:
constexpr static bool value = IsSame<decltype(test<T>(nullptr)), char>;
};
struct DeleteConstructor{
DeleteConstructor()=delete;
};
void Test1(){
std::cout<<boolalpha;
std::cout<<IsDefaultConstructibleT<DeleteConstructor>::value<<std::endl;//false
std::cout<<IsDefaultConstructibleT<std::string>::value<<std::endl;//true
}
// 基于SFINAE萃取的实现策略
// 方法核心是实现两个返回值类型不同的重载函数模板
template<typename T>
static char test(void*);
template<typename>
static long test(...);
//有些平台sizeof类型大小都是相同的,所以会出现如下类型定义
using SizeT1 = char(&)[1]; // sizeof 1
using SizeT2 = struct { char a[2];}; // 等价using SizeT2 = char(&)[2]; sizeof 2
template<typename T>
SizeT1 TEST(void*);
template<typename>
SizeT2 TEST(...);
// 早些实现技术中,基于返回值类型大小判断使用的是哪一个重载函数(也会用到0和enum)
template<typename T>
struct IsExistsConstructibleT{
enum {value = sizeof(test<T>(0)) == 1};
enum {result = sizeof(test<T>(0,2)) == 1};
enum {res1 = sizeof(TEST<T>(0)) == 1};
enum {res2 = sizeof(TEST<T>(0,2)) == 1};
};
void Test2(){
std::cout<<IsExistsConstructibleT<int>::value<<std::endl;// 1
std::cout<<IsExistsConstructibleT<int>::result<<std::endl;// 0
std::cout<<IsExistsConstructibleT<int>::res1<<std::endl;// 1
std::cout<<IsExistsConstructibleT<int>::res2<<std::endl;// 0
}
int main()
{
Test1();
Test2();
return 0;
}
基于SFINAE类型萃取
最新推荐文章于 2025-07-10 20:59:38 发布
222

被折叠的 条评论
为什么被折叠?



