The following actions may work as protection, but the member variable must be accessible ( public ), otherwise it will not work:
#include <type_traits> class Test { public: int* p; }; template< typename T > typename std::enable_if< std::is_pointer< decltype( T::p ) >::value >::type foo( T bla ) { static_assert( sizeof( T ) == 0, "T::p is a pointer" ); } template< typename T > void foo( T bla ) { } int main() { Test test; foo( test ); }
Living example
Of course, you need to know the name of the member variable to check, since in C ++ there is no general reflection mechanism.
Another way to avoid ambiguity is to create a has_pointer :
template< typename, typename = void > struct has_pointer : std::false_type {}; template< typename T > struct has_pointer< T, typename std::enable_if< std::is_pointer< decltype( T::p ) >::value >::type > : std::true_type {}; template< typename T > void foo( T bla ) { static_assert( !has_pointer< T >::value, "T::p is a pointer" );
Living example
Note that I just added static_assert as the first line of the function to get a nice, readable error message. Of course, you can also disable this feature, for example:
template< typename T > typename std::enable_if< !has_pointer< T >::value >::type foo( T bla ) {
Daniel Frey
source share