Конструктор для std::function<...>
является шаблонным , потому что он должен поддерживать любой тип ввода, похожий на функцию. Не существует единственного типа, который можно попытаться вывести, поэтому все ваши перегрузки можно построить; только позже в компиляции возникнет ошибка для несоответствия типов.
Вы можете сделать это:
GetInfo(item, static_cast<double(*)(ITEM*)>(GetLength));
Чтобы явно отказаться от других перегрузок.
Другими словами, по той же причине это не будет работать:
void foo(int);
void foo(void*);
struct bar
{
template <typename T>
bar(T f)
{
f(5);
}
};
bar b(foo);
Хотя тело конструктора для bar
будет работать только с void foo(int)
,
он хочет поддерживать любую функцию, в которой f(5)
будет работать, поэтому тип аргумента является шаблонным. Это позволяет любой функции работать в этом месте, что означает, что компилятор не может определить единственную наилучшую перегрузку для использования.
Я думаю, что одно решение на уровне языка предназначено для того, чтобы набор перегрузки действительно являлся функтором. То есть дано:
void foo(int);
void foo(void*);
template <typename T>
double foo(int, T);
Именование foo
(как в bar(foo)
или даже просто foo(5)
) приводит к экземпляру этого типа:
struct __foo_overload_set // internal
{
// forwarders
void operator()(int __arg0) const
{
// where __foo0 is the zeroth overload, etc...
return __foo0(__arg0);
}
void operator()(void* __arg0) const
{
return __foo1(__arg0);
}
template <typename __Arg1>
double operator()(int __arg0, __Arg1&& __arg1) const
{
return __foo2(__arg0, std::forward<__Arg1>(__arg1));
}
// converters
typedef void(*__foo0_type)(int);
operator __foo0_type() const
{
return __foo0;
}
typedef void(*__foo1_type)(void*);
operator __foo1_type() const
{
return __foo1;
}
template <typename T>
struct __foo2_type
{
typedef void(*type)(int, T);
};
template <typename T>
operator typename __foo2_type<T>::type() const
{
return __foo2;
}
};
Который, будучи вызванным сам по себе, будет компилироваться в нужном нам контексте. (AFAIK, он не вносит каких-либо двусмысленностей, которые еще не существуют, хотя он полностью не проверен.)