Предположим, что шаблон функции:
template <class T>
void foo(T /* dummy */) {...}
Предположим, что foo
вызывается так:
foo(Widget());
Будет ли объект Widget
построен в этом случае?
Этот пост задает аналогичный вопрос о неиспользуемых аргументах (и аргументы для фиктивных параметров, безусловно, не используются). Ответы предполагают, что, если функция не вызвана через указатель функции, неиспользуемые аргументы будут оптимизированы компилятором.
Однако рассмотрим следующий текст в разделе 2.5 Современный С++ от Alexandrescu:
Теперь скажем, что в вашем приложении есть правило: Объекты типа Widget - неприкасаемый старый код и должны принимать два аргумента при построении, а второй - фиксированное значение, такое как -1. У ваших собственных классов, полученных из Widget, нет этой проблемы.
...
В отсутствие частичной специализации функций единственным доступным инструментом является, опять же, перегрузка. Решением было бы передать фиктивный объект типа T и полагаться на перегрузку:
template <class T, class U> T* Create(const U& arg, T /* dummy */) { return new T(arg); } template <class U> Widget* Create(const U& arg, Widget /* dummy */) { return new Widget(arg, -1); }
Такое решение повлекло бы за собой накладные расходы на создание произвольно сложного объекта, который остается неиспользованным.
Это говорит о том, что компиляторы недостаточно умны, чтобы избежать построения аргумента для параметра фиктивного файла...
Итак, что правильно? Если Alexandrescu прав, то почему эта оптимизация не происходит?