#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, используя шрифты Брайля: то, что произвольно для машины, не обязательно так уж произвольно для нас!