How to write `is_complete` template?
It might be a bit late, but so far, no C++ 11 solution worked for both complete and abstract types.
So, here you are.
With VS2015 (v140), g++ >= 4.8.1, clang >= 3.4, this is working:
template <class T, class = void>
struct IsComplete : std::false_type
{};
template <class T>
struct IsComplete< T, decltype(void(sizeof(T))) > : std::true_type
{};
Thanks to Bat-Ulzii Luvsanbat: https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
With VS2013 (V120):
namespace Details
{
template <class T>
struct IsComplete
{
typedef char no;
struct yes { char dummy[2]; };
template <class U, class = decltype(sizeof(std::declval< U >())) >
static yes check(U*);
template <class U>
static no check(...);
static const bool value = sizeof(check< T >(nullptr)) == sizeof(yes);
};
} // namespace Details
template <class T>
struct IsComplete : std::integral_constant< bool, Details::IsComplete< T >::value >
{};
This one is inspired from the internets and static assert that template typename T is NOT complete?
template<class T>
struct is_complete {
static T & getT();
static char (& pass(T))[2];
static char pass(...);
static const bool value = sizeof(pass(getT()))==2;
};
The answer given by Alexey Malistov can be used on MSVC with a minor modification:
namespace
{
template<class T, int discriminator>
struct is_complete {
static T & getT();
static char (& pass(T))[2];
static char pass(...);
static const bool value = sizeof(pass(getT()))==2;
};
}
#define IS_COMPLETE(X) is_complete<X,__COUNTER__>::value
Unfortunately, the __COUNTER__
predefined macro is not part of the standard, so it would not work on every compiler.