Обновление: это ошибка gcc, которая была исправлена в gcc> = 4.4. Bugzilla . Кроме того, пересмотрен мой ответ с сокращенным контрольным примером.
Эта проблема состоит из двух компонентов: способ boost :: function принимает указатель на функцию и ошибка gcc.
boost :: function - Что-то странное в сообщении об ошибке, которое вы указали в вопросе; не существует кандидата-конструктора, который принимает что-либо подобное адресу функции. Копаясь в boost :: function src, соответствующий конструктор (пропуская аргумент enable_if):
template<typename Functor>
function(Functor f) : base_type(f) {}
Так что boost :: function совсем не поможет вам в определении типа указателя на функцию; если функция перегружена, адрес должен быть приведен для указания ее типа. Если используется адрес перегруженной функции, вышеупомянутый шаблон не может быть создан, и поэтому соответствующий конструктор не отображается в сообщении об ошибке.
gcc bug - Если вы снова посмотрите на заголовок stl_algobase.h, вы увидите, что есть два шаблона с именем max, версия с двумя параметрами и версия с одним параметром. Это не должно быть проблемой с вашим кодом, правда? Термин &max<int>
должен обозначать версию с одним параметром и принимать ее адрес. Однако этого не происходит. Вы можете увидеть проблему в сокращенном (без заголовка) тесте:
template <class T>
const T& max(const T& x, const T& y){
return x > y ? x : y;
}
template <class T, class C>
const T& max(const T& x, const T& y, C comp){
return comp(x, y) ? y : x;
}
template <class R, class A0, class A1>
struct functor{
template <class F>
functor(F f) : f(f) {}
R (*f)(A0, A1);
};
int main(void){
functor<const int&, const int&, const int&> func(&max<int>);
return 0;
}
Приведенный выше код приводит к unresolved overloaded function type
с gcc 4.3.4. Исправление заключается в удалении определения template <class T, class C> max(...){...}
или добавлении static_cast<const int& (*)(const int&, const int&)>(...)
вокруг адреса функции. Я предполагаю, что проблема связана с неправильным применением частичной явной спецификации параметров, которая указана в стандарте. Это позволяет вам не использовать конечные параметры шаблона для таких вещей, как указание типа возвращаемого значения, а не типов аргументов. То есть компилятор создает оба шаблона, когда он должен создавать только полностью указанный шаблон. Хотя это спорная гипотеза, поскольку ошибка была исправлена в gcc> = 4.4.
Так как не следует взламывать stl_algobase.h;), работа вокруг Висенте предполагает, что он правильный, а именно приведение указателя функции к нужному типу указателя функции const int& (*)(const int&, const int&)
. В вашем коде приведение не работает, потому что, как указывает GMan, вы приводите к boost :: function <...>, который ничего не делает для устранения неоднозначности указателя на функцию.