Why does aggregate-initializing a non-type template parameter with a placeholder for a deduced class type fail to compile?

Viewed 120

Consider the following code:

struct Base_string { char data[1 << 5]; };

template<typename Base>
struct Derived: Base { };

Derived(char const*) -> Derived<Base_string>;

template<Derived>
struct S { };

S<{"Test"}> s; // Error

The last line, in which S is instantiated, does not compile. I expected it to work, because [temp.arg.nontype#1] states that:

If the type T of a template-parameter contains [...] a placeholder for a deduced class type, the type of the parameter is the type deduced for the variable x in the invented declaration T x = template-argument;

In my case, this invented declaration would look like this: Derived x = {"Test"};, and actually declaring a variable like this in the program produces no errors - the type is deduced correctly.
Also, I think the problem isn't in the aggregate-initialization syntax itself - changing the definition of the template S to:

template<Base_string>
struct S { };

and instantiating it the same way (S<{"Test"}> s;) produces no errors.

I know that I could simply specify the type explicitly, like so: S<Derived{"Test"}> s;, but I'm not looking for a work-around, I want to understand why deduction fails here.

0 Answers
Related