Does anyone know how to detect a constructor with one argument? For example, this struct should have a negative result:
struct MyStruct
{
MyStruct( int x, int x2 ) : y( x ) {}
int y;
};
I have here a nice SFINAE check to see if a class or struct as a constructor with a specific number of arguments. Here's the one for argument count of 3:
template <typename T>
struct HasCtor3Args
{
struct Any { template <typename U> operator U( void ); };
template <typename U>
static int32 SFINAE( decltype( U( Any( ), Any( ), Any( ) ) ) * );
template <typename U>
static int8 SFINAE( ... );
static const bool value = sizeof( SFINAE<T>( NULL ) ) == sizeof( int32 );
};
This seems to work just fine, as the Any
struct can convert to whatever types the parameters ought to be. However the issue is when trying to detect a constructor with just one argument. The SFINAE check seems to always return true due to defaulting Any
to the same type as T
thus detecting a copy constructor.
Edit and Update: I've made a few attempts, none seem to be a go... This was the closest I can get, but doesn't work as it always returns true. The idea was to try and get the copy constructor to resolve instead of the first "catch all" call:
template <typename T>
struct HasCtor1Args
{
struct Any
{
template <typename U>
operator U( ) const;
};
template <typename U>
static int32 SFINAE( decltype( U( Any( ) ) ) * );
// Try to catch the copy ctor here
T MakeT( void );
template <typename U>
static int8 SFINAE( decltype( U( MakeT( ) ) ) * );
template <typename U>
static int8 SFINAE( ... );
static const bool value = sizeof( SFINAE<T>( NULL ) ) == sizeof( int32 );
};
I also tried using the explicit keyword, along with the = delete feature for C++11, then realized the compiler I need to use (Microsoft's) does not allow this. I also tried using std::enable_if on the conversion type U, although I ran into the error that function template parameters cannot be defaulted.