Стандарт C++ гарантирует следующее?:
template<typename T>
void function(T (&)[1]);
template<typename T>
void function(T*);
int a[1];
function(a); // first function gets called, not second version
Да, это гарантировано, но причина отличается от того, что говорит GMan. Будет выбрана перегрузка «массив длины 1», потому что она более специализирована, чем вторая в частичном порядке шаблонных функций. По сути, это означает, что аргумент в форме T (&) [1]
всегда будет соответствовать второму аргументу шаблона в форме T *
, поэтому всегда будет выбираться первая перегрузка. когда последовательности преобразования не решают.
Из 13.3.3:
Учитывая эти определения, жизнеспособный функция F1 определена как лучшая функция, чем другая жизнеспособная функция F2, если для всех аргументов i ICSi (F1) является не худшая последовательность преобразования, чем ICSi (F2), а затем
для некоторого аргумента j, ICSj (F1) является лучшей последовательностью преобразования, чем ICSj (F2), или, если не так,
F1 - не шаблонная функция, а F2 - специализация шаблонной функции, или, если не так,
F1 и F2 являются шаблонными функциями, а шаблон функции для F1 - более специализированный, чем шаблон для F2 согласно частичному правила заказа, описанные в 14.5.5.2, или, если не так,
...
На обычные функции влияет только первый элемент; когда какие-либо функции шаблона входят в набор функций-кандидатов, второй или третий элемент может решить.Причина, по которой мы этого хотим, заключается в том, что мы хотим иметь возможность писать, казалось бы, неоднозначные шаблонные перегрузки. Например. В противном случае
template <class T> void f(T);
template <class T> void f(T*);
будет неоднозначным для int *
. В C ++ 0x вы даже можете писать такие объявления, как:
template <class ...Ts> void f(const Ts&... args);
template <class T, class ... Ts> void f(const T& a, const Ts&... args);
, и второе будет выбираться всякий раз, когда есть хотя бы один аргумент.