C++11 has test
template<typename T_>
class Has___
{
public:
template<typename U_>
static typename std::conditional<$what<T_>$::value, std::true_type, std::false_type>
check(int);
template<typename>
static std::false_type
check(...);
static const bool value = decltype(check<T_>(0))::type::value;
};
C++11 enable_if
#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;
}
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";
}
template<class T, class... Args>
std::enable_if_t<!std::is_trivially_constructible<T,Args&&...>::value>
construct(T* t,Args&&... args)
{
std::cout << "constructing non-trivially constructible T\n";
new(t, detail::inplace_t{}) T(args...);
}
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";
}
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();
}
template<class T,
typename = std::enable_if_t<std::is_array<T>::value> >
void destroy(T* t)
{
for(std::size_t i = 0; i < std::extent<T>::value; ++i) {
destroy((*t)[i]);
}
}
template<class T, class Enable = void>
class A {};
template<class T>
class A<T, typename std::enable_if<std::is_floating_point<T>::value>::type> {
};
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;
A<double> a2;
}