Был ли стандарт С++14 дефектным/недоопределенным в отношении вывода параметра функции типа массива из списка инициализаторов?
Неудивительно, что следующая программа
// #1
template<typename T, std::size_t N>
void f(T (&&)[N]) {}
int main() { f({1,2,3}); }
по-видимому, правильно сформирован в С++ 14 (ну, по крайней мере, все компиляторы, которые я пробовал, принимают его).
Однако кажется, что это не поддерживается стандартом С++ 14, в частности, что
T
и
N
можно вывести из аргумента списка инициализаторов?
Данный тип
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
:)