8

The "Template argument deduction for class templates" proposal (P0091R2) contains the following example:

template<class ... Ts> struct X { X(Ts...) };
X x1{1}; // OK X<int>
X x11; // OK X<>

(Apart from the fact that the constructor definition is missing a body), the example seems to suggest that a variadic class template constructed with zero argument will be deduced with an empty parameter pack.

Unfortunately, the latest version of g++ does not agree:

int main()
{
    X x1{1};
    X x11;
}

 In function 'int main()':
 error: invalid use of template-name 'X' without an argument list
 X x11;
 ^
 note: class template argument deduction requires an initializer

example on wandbox


I could not find explicit wording in the proposal that clarifies this interaction. Is g++ wrong here?

Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416
  • `X x11{};` works. – ildjarn Nov 11 '16 at 21:57
  • 1
    I'd say gcc implementation is in the experimental stage right now. i.e. `vector v{2,3}` works, but `vector v{2,3,4}` yields an error that `'int' is not a class, struct, or union type`. – krzaq Nov 11 '16 at 22:02
  • @krzaq: it seems that it tries to call [constructor (2)](http://en.cppreference.com/w/cpp/container/vector/vector) for that particular case. I wonder if this is actually intended *(i.e. what are the rules for disambiguation in these cases)*. By the way, I am aware that gcc is in the experimental stage - my interest is filing bug reports where appropriate. – Vittorio Romeo Nov 11 '16 at 22:07
  • @VittorioRomeo the vector is filled with values 2 and 3, not with 3 and 3. It does call the constructor you mentioned if you initialize it with `vector v(2,3)` – krzaq Nov 11 '16 at 22:08
  • In retrospect, I think that `vector v{1,2,3}` failing does make sense, as `vector{1,2,3,4}` fails as well. `vector v{{1,2,3}}` compiles as intended. – Vittorio Romeo Nov 11 '16 at 22:08
  • 1
    Don't you just love the "universal construction" syntax? It's even more confusing than the earlier one... – user541686 Nov 11 '16 at 22:09
  • @krzaq: ah, I see the inconsistency now - I assumed the binary version called constructor (2) as well. – Vittorio Romeo Nov 11 '16 at 22:11

1 Answers1

9

This is now well-formed after P0620R0 removed the cited restriction right before C++17's publication.

Previous answer kept for reference:


N4618 [dcl.type.class.deduct]/1:

If a placeholder for a deduced class type appears as a decl-specifier in the decl-specifier-seq of a simple-declaration, the init-declarator of that declaration shall be of the form

declarator-id attribute-specifier-seqopt initializer

The initializer is not optional.

T.C.
  • 133,968
  • 17
  • 288
  • 421