Есть ли какая-либо разница между выводимым шаблонным аргументом и автоматическим аргументом?

#c #templates #c 20 #template-argument-deduction

#c #шаблоны #c 20 #шаблон-аргумент-вывод

Вопрос:

Отличаются ли эти две функции каким-либо значимым образом? Есть ли какая-либо причина, по которой обычно предпочитают один другому?

 void foo(auto x, auto amp;... y) { /* ... */ }

template<typename T, typename... Tx>
void foo(T x, Tx amp;... y) { /* ... */ }
  

Я бы предпочел использовать первый, когда мне не нужен удобный тип T, потому что он короче… но мне интересно, есть ли какие-либо недостатки.

Ответ №1:

Он буквально определен как эквивалентный [dcl.fct]

Сокращенный шаблон функции — это объявление функции, содержащее один или несколько заполнителей общего типа параметров. Сокращенный шаблон функции эквивалентен шаблону функции, список шаблонов-параметров которого включает в себя один шаблон-параметр изобретенного типа для каждого заполнителя типа универсального параметра объявления функции в порядке появления.

Где заполнителями общего типа являются auto .

Как и в случае с большинством эквивалентных синтаксисов, все сводится к соглашению: выберите один и придерживайтесь его.

Ответ №2:

В показанном примере нет абсолютно никакой разницы между двумя версиями. Оба являются неограниченными шаблонами функций, которые принимают 1 аргумент любого типа по значению, а затем 0 или более аргументов любых типов по ссылке.

Лично я, как и вы, предпочитаю первый, поскольку он меньше печатается и его легче читать.


Вы должны быть осторожны при замене одной формы на другую, например, заменяя:

 template<typename T>
void foo(T x, T y) { /* ... */ }  // #1
  

с

 void foo(auto x, auto y) { /* ... */ }  // #2 // not equivalent to #1
  

неверно, поскольку нет требования для x и y иметь тот же тип в #2 , в отличие от in #1 .

Ответ №3:

Отличаются ли эти две функции каким-либо значимым образом?

ДА. Последнее приводит к более повторяющимся стрессовым травмам, чем первое, не в последнюю очередь потому, что удары головой о клавиатуру являются повторяющимися и приводят к травмам.

Большая часть разработки программного обеспечения связана с ограничениями и потребностями людей, а не машин. Даже, казалось бы, машинно-ориентированные аспекты, такие как производительность, имеют значение только в той степени, в какой это может волновать некоторых людей (будь то некоторые пользователи, которые хотели бы более плавного взаимодействия, или разработчики, чьи тела просто не выдержат еще одного раунда борьбы на мечах в коридоре, или акционеры, которых бросает в пот, когда кто-то размером с Facebook видит 1% падение производительности в их инфраструктуре — в каком масштабе потери измеряются в золотых шарикоподшипниках, свободно выпадающих из носика большой воронки).

Почти Ada-подобная подробность, в которой погряз весь template окружающий синтаксис, ни в малейшей степени не эргономична. Эргономика играет большую роль в том, чтобы сделать нас счастливыми в конце дня, так что да, это, безусловно, имеет смысл в полном смысле этого слова. Это не та разница, которая имеет большое значение для компилятора, но по этому стандарту мы будем писать машинный код непосредственно в базе 2 ^ 6, используя шрифты Брайля: то, что произвольно для машины, не обязательно так уж произвольно для нас!