title: ctor is ambiguous between single and multiple std::initializer_list ctors on clang and gcc but not msvc
body: <p>I have a nested initializer_list ctor for creating 2D matrixes. Works great. But then I decided to add a simplified row vector matrix (n rows, 1 col) using a single initializer list. This is so I could create a row matrix like this: <code>Matrix2D&lt;int&gt; x{1,2,3}</code> instead of having to do this: <code>Matrix2D&lt;int&gt; x{{1},{2},{3}}</code>. Of course this required a separate ctor.</p>
  <p>Everything worked including in constexpr with MSVC. But when checked using gcc and clang I'm getting ambiguous ctors. Seems pretty clear to me when the lists are nested and MSVC operates exactly as expected.</p>
  <p>Here's the code:</p>
  <pre><code>// Comment out next line for only nested initializer_list ctor
  #define INCLUDE_EXTRA_CTOR
  #include &lt;memory&gt;
  #include &lt;numeric&gt;
  #include &lt;initializer_list&gt;
  #include &lt;exception&gt;
  #include &lt;stdexcept&gt;
  #include &lt;concepts&gt;
  
  using std::size_t;
  template &lt;typename T&gt;
  class Matrix2D {
      T* const pv;    // pointer to matrix contents
  public:
      const size_t cols;
      const size_t rows;
  
      // default ctor;
      Matrix2D() noexcept : pv(nullptr), cols(0), rows(0) {}
  
      // 2D List initialized ctor
      Matrix2D(std::initializer_list&lt;std::initializer_list&lt;T&gt;&gt; list) :
          pv((list.begin())-&gt;size() != 0 ? new T[list.size() * (list.begin())-&gt;size()] : nullptr),
          cols(pv != nullptr ? (list.begin())-&gt;size() : 0),
          rows(pv != nullptr ? list.size() : 0)
      {
          if (pv == nullptr)
              return;
          for (size_t row = 0; row &lt; list.size(); row++)
          {
              if (cols != (list.begin() + row)-&gt;size())
                  throw std::runtime_error(&quot;number of columns in each row must be the same&quot;);
              for (size_t col = 0; col &lt; cols; col++)
                  pv[cols * row + col] = *((list.begin() + row)-&gt;begin() + col);
          }
      }
  #ifdef INCLUDE_EXTRA_CTOR
      // Row initialized ctor, rows=n, cols=1;
      Matrix2D(std::initializer_list&lt;T&gt; list) :
          pv(list.size() != 0 ? new T[list.size()] : nullptr),
          cols(pv != nullptr ? 1 : 0),
          rows(pv != nullptr ? list.size() : 0)
      {
          if (pv == nullptr)
              return;
          for (size_t row = 0; row &lt; rows; row++)
          {
              pv[row] = *(list.begin() + row);
          }
      }
  #endif
  
      // dtor
      ~Matrix2D() { delete[] pv; }
  };
  
  int main()
  {
      // Tests of various possible null declarations 
      Matrix2D&lt;int&gt; x1{ };        // default
      Matrix2D&lt;int&gt; x2{ {} };     // E0309, nested init list with 1 row, 0 cols, forced to 0 rows, 0 cols
      Matrix2D&lt;int&gt; x3{ {},{} };  // E0309, nested init list with 2 rows, 0 cols, forced to 0 rows, 0 cols
  
      // typical declaration
      Matrix2D&lt;int&gt; x4{ {1,2},{3,4},{5,6} };  // nested init list with 3 rows, 2 cols
      // standard row vector declaration
      Matrix2D&lt;int&gt; x5{ {1},{2},{3} };  // E0309, init list with 3 rows, 1 col
  
  #ifdef INCLUDE_EXTRA_CTOR
      // row vector declaration
      Matrix2D&lt;int&gt; x6{ 1,2,3 };  // init list with 3 rows, 1 col
  #endif
  }
  </code></pre>
  <p>E0309 is the MSVC intellisense ambiguous ctor error. However, compiles w/o error
  Why are gcc and clang deductions ambiguous? Is there a workaround?</p>
  <p><a href="https://godbolt.org/z/bxvYGe5E1" rel="nofollow noreferrer">Compiler Explorer</a></p>