Title
Deducing array bound and element type from initializer list
Status
cd4
Section
13.10.3.2 [temp.deduct.call]
Submitter
Peter Dimov

Created on 2012-12-01.00:00:00 last changed 95 months ago

Messages

Date: 2014-11-15.00:00:00

[Moved to DR at the November, 2014 meeting.]

Date: 2014-02-15.00:00:00

Proposed resolution (February, 2014):

  1. Change 13.10.3.2 [temp.deduct.call] paragraph 1 as follows:

  2. Template argument deduction is done by comparing each function template parameter type (call it P) with the type of the corresponding argument of the call (call it A) as described below. If P is a dependent type, removing references and cv-qualifiers from P gives std::initializer_list<P'> or P'[N] for some P' and N, and the argument is an a non-empty initializer list (9.4.5 [dcl.init.list]), then deduction is performed instead for each element of the initializer list, taking P' as a function template parameter type and the initializer element as its argument, and in the P'[N] case, if N is a non-type template parameter, N is deduced from the length of the initializer list. Otherwise, an initializer list argument causes the parameter to be considered a non-deduced context (13.10.3.6 [temp.deduct.type]). [Example:

      template<class T> void f(std::initializer_list<T>);
      f({1,2,3});              // T deduced to int
      f({1,"asdf"});           // error: T deduced to both int and const char*
    
      template<class T> void g(T);
      g({1,2,3});              // error: no argument deduced for T
    
      template<class T, int N> void h(T const(&)[N]);
      h({1,2,3});              // T deduced to int, N deduced to 3
    
      template<class T> void j(T const(&)[3]);
      j({42});                 // T deduced to int, array bound not considered
    
      struct Aggr { int i; int j; };
      template<int N> void k(Aggr const(&)[N]);
      k({1,2,3});              // error: deduction fails, no conversion from int to Aggr
      k({{1},{2},{3}});        // OK, N deduced to 3
    
      template<int M, int N> void m(int const(&)[M][N]);
      m({{1,2},{3,4}});        // M and N both deduced to 2
    
      template<class T, int N> void n(T const(&)[N], T);
      n({{1},{2},{3}},Aggr()); // OK, T is Aggr, N is 3
    

    end example] For a function parameter pack...

  3. Change the penultimate bullet of 13.10.3.6 [temp.deduct.type] paragraph 5 as follows:

  4. The non-deduced contexts are:

    • ...

    • A function parameter for which the associated argument is an initializer list (9.4.5 [dcl.init.list]) but the parameter does not have std::initializer_list or reference to possibly cv-qualified std::initializer_list type a type for which deduction from an initializer list is specified (13.10.3.2 [temp.deduct.call]). [Example:...

    • A function parameter pack that does not occur at the end of the parameter-declaration-list.

Date: 2013-03-15.00:00:00

Additional note (March, 2013):

The element type should also be deducible.

Date: 2012-12-01.00:00:00

Currently, 13.10.3.2 [temp.deduct.call] paragraph 1 says,

Template argument deduction is done by comparing each function template parameter type (call it P) with the type of the corresponding argument of the call (call it A) as described below. If removing references and cv-qualifiers from P gives std::initializer_list<P'> for some P' and the argument is an initializer list (9.4.5 [dcl.init.list]), then deduction is performed instead for each element of the initializer list, taking P' as a function template parameter type and the initializer element as its argument. Otherwise, an initializer list argument causes the parameter to be considered a non-deduced context (13.10.3.6 [temp.deduct.type]).

It would seem reasonable, however, to allow an array bound to be deduced from the number of elements in the initializer list, e.g.,

  template<int N> void g(int const (&)[N]);
  void f() {
    g( { 1, 2, 3, 4 } );
  }
History
Date User Action Args
2017-02-06 00:00:00adminsetstatus: drwp -> cd4
2015-05-25 00:00:00adminsetstatus: dr -> drwp
2015-04-13 00:00:00adminsetmessages: + msg5418
2014-11-24 00:00:00adminsetstatus: ready -> dr
2014-03-03 00:00:00adminsetmessages: + msg4856
2014-03-03 00:00:00adminsetstatus: drafting -> ready
2013-05-03 00:00:00adminsetstatus: open -> drafting
2013-03-18 00:00:00adminsetmessages: + msg4297
2012-12-01 00:00:00admincreate