#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;
}
template<typename T>
struct IsDefaultConstructibleT{
private:
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;
std::cout<<IsDefaultConstructibleT<std::string>::value<<std::endl;
}
template<typename T>
static char test(void*);
template<typename>
static long test(...);
using SizeT1 = char(&)[1];
using SizeT2 = struct { char a[2];};
template<typename T>
SizeT1 TEST(void*);
template<typename>
SizeT2 TEST(...);
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;
std::cout<<IsExistsConstructibleT<int>::result<<std::endl;
std::cout<<IsExistsConstructibleT<int>::res1<<std::endl;
std::cout<<IsExistsConstructibleT<int>::res2<<std::endl;
}
int main()
{
Test1();
Test2();
return 0;
}