Указание значения по умолчанию для аргумента функции шаблона
Не могли бы вы объяснить, почему следующий код не компилируется? Очевидным обходным решением является добавление 1-аргументной перегрузки Apply
, есть ли более простая?
template <typename T>
T Identity(const T& i_val)
{
return i_val;
}
template <typename Val, typename Fn>
Val Apply(const Val& v, Fn fn = Identity<Val>)
{
return fn(v);
}
int main() {
Apply(42); // error: no matching function for call to 'Apply(int)'
Apply(42, Identity<int>); // OK
return 0;
}
Ответы
Ответ 1
Поиск функции для вызова состоит из:
1. создание набора кандидатов, который включает в себя вывод аргумента шаблона
2. определение наилучшей перегрузки
Если я правильно понимаю стандарт, в выводе аргументов шаблона принимают участие только фактические аргументы функции (т.е. не по умолчанию). Поэтому из аргумента 42
единственное, что может сделать компилятор, это Val
= int
. Перегрузка не входит в набор кандидатов, и аргумент по умолчанию никогда не просматривается.
Ответ 2
Вычисление аргумента шаблона не работает таким образом - вы не можете вывести тип аргумента из значения по умолчанию. В С++ 11 вы можете указать аргумент шаблона по умолчанию:
template <typename Val, typename Fn = Val(&)(Val const &)>
Val Apply(const Val& v, Fn fn = Identity<Val>)
{
return fn(v);
}
Ответ 3
Применить - это шаблонная функция. Вам нужно сделать Apply<MyValueType,MyFuncType>(42);
Вы можете разумно ожидать, что компилятор выведет Val
как int
, но вы не можете ожидать, что он выведет тип функции, даже если вы указали параметр по умолчанию. В результате этого не будет выведено, что вы пытаетесь вызвать это объявление функции Apply
.