SU3
SU3

Reputation: 5387

List initialization of function template arguments with automatic template type deduction

Here's the setup to illustrate the problem.

template <typename T>
struct opt {
  const char* name;
  T x;

  template <typename X>
  opt(const char* name, X&& x)
  : name(name), x(std::forward<X>(x)) { }
};

template <typename T>
opt(const char*, T&&) -> opt< some_type_transformation<T> >;

template <typename... T>
void function(opt<T>&&... opts) {
  // do something with the passed arguments
}

With this, the following syntax can be used.

function(opt("a",1),opt("b",2.),opt("c",3u));

But the following does not work.

function({"a",1},{"b",2.},{"c",3u});

Theoretically, there is enough information to figure out what to do in the second case, since the function takes arguments only of type opt<T>, and T can be deduced using the defined deduction guide.

Can something be done to enable the second, terser syntax?

Upvotes: 0

Views: 238

Answers (1)

Nicol Bolas
Nicol Bolas

Reputation: 473272

Template argument deduction relies on using the type of an expression to match a pattern defined in a template parameter.

Copy-list-initialization (list-initialization where the name of the type being used is not immediately available where the braced-init-list is used) is a process where a sequence of values is matched against the declaration of a named type to figure out which initialization form to use. That is, it involves some degree of deduction.

What you're trying to do effectively involves double deduction, since a braced-init-list by itself doesn't have a well-defined type. You would need to use the pattern from the template parameter to match some set of possible types and their constructors against the braced-init-list's members.

Such a thing would be theoretically possible in some cases of template argument deduction, but spelling out exactly what those cases are is exceedingly difficult, as the way template argument deduction works is itself pretty complex. As such, the standard takes the easy way out and just forbids it entirely: you cannot use copy-list-initialization on a parameter involved in template argument deduction, period.

So there's no shorter form out there. You're just going to have to spell it out.

Upvotes: 1

Related Questions