Boost logo

Boost :

Subject: Re: [boost] A proposal for the creation of a new module, Core Type Traits
From: Stephen Kelly (hello_at_[hidden])
Date: 2015-01-09 13:41:19


John Maddock wrote:

>>> there's an opportunity here to remove all that obfuscation and crud and
>>> produce something that's actually halfway readable and maintainable.
>>
>> Just on the topic of maintenance:
>>
>> A C++17 style voider works with GCC 3.2 and later, VS8 and later and
>> various HP aCC, Sun Studio, Intel and other compilers listed here:
>>
>> https://open.cdash.org/index.php?project=CMake&date=2015-01-05
>>
>> Only VS 7.1 chokes on it.
>
> What's a C++ 17 style voider?

See

 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3911.pdf

 https://www.youtube.com/watch?feature=player_detailpage&v=a0FliKwcwXE#t=1740

Even if using VS8, GCC3.2 etc you can still do this:

template<typename>
struct voider { typedef void type; };

struct true_type
{
  enum { value = true };
};
struct false_type
{
  enum { value = false };
};

template<typename T, typename = void>
struct HasSecondType : false_type {};

template<typename T>
struct HasSecondType<T,
    typename voider<typename T::second_type>::type> : true_type {};

template<typename T, T>
struct PointerHelper {};

template<typename T, typename = void>
struct HasSomeMemberFunc : false_type {};

template<typename T>
struct HasSomeMemberFunc<T,
    typename voider<PointerHelper<int(T::*)(int), &T::somemember> >::type> :
true_type {};

template<typename T, typename = void>
struct HasSomeMemberData : false_type {};

template<typename T>
struct HasSomeMemberData<T,
    typename voider<PointerHelper<double T::*, &T::data> >::type> :
true_type {};

struct A
{
  int somemember(int);
  int somemember(double);

  double data;
};

struct B
{
  int data;
  double otherData;
};

template<bool b>
class myStaticAssert;

template<>
class myStaticAssert<true> {};

#define My_Join(A, B) My_Joiner(A, B)
#define My_Joiner(A, B) A ## B

#define My_StaticAssert(cond, message) \
  enum {My_Join(assert, __LINE__) = sizeof(myStaticAssert<cond>)};

My_StaticAssert(HasSomeMemberFunc<A>::value, "");
My_StaticAssert(!HasSomeMemberFunc<B>::value, "");
My_StaticAssert(HasSomeMemberData<A>::value, "");
My_StaticAssert(!HasSomeMemberData<B>::value, "");

I'll leave it as an excercise for you to macro-ize the HasSomeMemberData etc
structs.

Thanks,

Steve.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk