Я пытаюсь понять, почему std::function
не может отличить перегруженные функции.
#include <functional>
void add(int,int){}
class A {};
void add (A, A){}
int main(){
std::function <void(int, int)> func = add;
}
В приведенном выше коде function<void(int, int)>
может соответствовать только одной из этих функций, и все же он терпит неудачу. Почему это так? Я знаю, что могу обойти это, используя лямбда или указатель на функцию, а затем сохранит функцию функции в функции. Но почему это не удается? Разве не ясно, какая функция я хочу выбрать? Пожалуйста, помогите мне понять, почему это не удается, поскольку я не могу понять, почему в этом случае сбой шаблона не работает.
Ошибки компилятора, которые я использую для этого, следующие:
test.cpp:10:33: error: no viable conversion from '<overloaded function type>' to
'std::function<void (int, int)>'
std::function <void(int, int)> func = add;
^ ~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__functional_03:1266:31: note:
candidate constructor not viable: no overload of 'add' matching
'std::__1::nullptr_t' for 1st argument
_LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__functional_03:1267:5: note:
candidate constructor not viable: no overload of 'add' matching 'const
std::__1::function<void (int, int)> &' for 1st argument
function(const function&);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__functional_03:1269:7: note:
candidate template ignored: couldn't infer template argument '_Fp'
function(_Fp,
^
1 error generated.
EDIT. В ответ на вопрос MSalters я сделал несколько поисков на этом форуме и нашел точную причину, почему это не удается. Я получил ответ от ответа Наваза в этом сообщении .
У меня есть копия, вставленная из его ответа здесь:
int test(const std::string&) {
return 0;
}
int test(const std::string*) {
return 0;
}
typedef int (*funtype)(const std::string&);
funtype fun = test; //no cast required now!
std::function<int(const std::string&)> func = fun; //no cast!
Итак, почему std::function<int(const std::string&)>
не работает так, как работает funtype fun = test
?
Ну, ответ заключается в том, что std::function
может быть инициализирован любым объектом, , поскольку его конструктор templatized, который не зависит от аргумента шаблона, который вы передали в std::function
.