Был ли стандарт С++14 дефектным/недоопределенным в отношении вывода параметра функции типа массива из списка инициализаторов?

Неудивительно, что следующая программа

      // #1
template<typename T, std::size_t N>
void f(T (&&)[N]) {}

int main() { f({1,2,3}); }

по-видимому, правильно сформирован в С++ 14 (ну, по крайней мере, все компиляторы, которые я пробовал, принимают его).

Однако кажется, что это не поддерживается стандартом С++ 14, в частности, что Tи Nможно вывести из аргумента списка инициализаторов?

[temp.deduct.type]/3.4

Данный тип Pможет состоять из ряда других типов, шаблонов и нетиповых значений:

  • [...]
  • /3.4 Тип массива включает в себя тип элемента массива и значение связанного массива.

объясняет, почему дедукция успешна для следующего примера:

      template<typename T, std::size_t N>
void f(T (&)[N]) {}

int main() { 
    int arr[] = {1, 2, 3};  // #2
    f(arr);
}

где конкретно [dcl.init.aggr]/4 управляет этим #2объявляет и массив размера 3(даже если он опущен из типа в объявлении).

Однако в контексте вызова функции согласно [temp.deduct.type]/5.6

Параметр функции, для которого связанный аргумент является списком инициализаторов ([dcl.init.list]), но параметр не имеет или не ссылается на, возможно, квалифицированный cv std::initializer_listтип.

... это невыведенный контекст.

Начиная со стандарта C++17 и далее [temp.deduct.call]/1 был обновлен, чтобы указать, что аргумент типа массива может быть выведен из (непустого) списка инициализаторов, но этого не было в C+. +14 standard и [temp.deduct.type]/5.6 в отношении невыведенных контекстов явно ссылается на [temp.deduct.call]/1 для исключений из правила.

Был ли это дефект/недостаточная спецификация стандарта С++ 14?

  • Если да, есть ли соответствующий отчет о дефекте (1) ?
  • Если нет, то какие разделы стандарта C++14 охватывают это #1выше правильно сформирован?

(1) Я пытался найти его сам, но безуспешно.

1 ответ

Это ДР 1591.

Казалось бы разумным... разрешить вывод связанного массива из количества элементов в списке инициализаторов, например,

         template<int N> void g(int const (&)[N]);
  void f() {
    g( { 1, 2, 3, 4 } );
  }

Будучи DR, он задним числом применяется к C++14.


NB: Кажется, user9585016 опередил меня , но я нашел его самостоятельно через git вину из templates.tex:)

Другие вопросы по тегам