title: SFINAE - Detect constructor with one argument
body: <p>Does anyone know how to detect a constructor with one argument? For example, this struct should have a negative result:</p>
  
  <pre><code>struct MyStruct
  {
    MyStruct( int x, int x2 ) : y( x ) {}
    int y;
  };
  </code></pre>
  
  <p>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:</p>
  
  <pre><code>template &lt;typename T&gt;
  struct HasCtor3Args
  {
    struct Any { template &lt;typename U&gt; operator U( void ); };
  
    template &lt;typename U&gt;
    static int32 SFINAE( decltype( U( Any( ), Any( ), Any( ) ) ) * );
  
    template &lt;typename U&gt;
    static int8 SFINAE( ... );
  
    static const bool value = sizeof( SFINAE&lt;T&gt;( NULL ) ) == sizeof( int32 );
  };
  </code></pre>
  
  <p>This seems to work just fine, as the <code>Any</code> 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 <code>Any</code> to the same type as <code>T</code> thus detecting a copy constructor.</p>
  
  <p><strong>Edit and Update</strong>:
  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:</p>
  
  <pre><code>template &lt;typename T&gt;
  struct HasCtor1Args
  {
    struct Any
    {
      template &lt;typename U&gt;
      operator U( ) const;
    };
  
    template &lt;typename U&gt;
    static int32 SFINAE( decltype( U( Any( ) ) ) * );
  
    // Try to catch the copy ctor here
    T MakeT( void );
    template &lt;typename U&gt;
    static int8 SFINAE( decltype( U( MakeT( ) ) ) * );
  
    template &lt;typename U&gt;
    static int8 SFINAE( ... );
  
    static const bool value = sizeof( SFINAE&lt;T&gt;( NULL ) ) == sizeof( int32 );
  };
  </code></pre>
  
  <p>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.</p>