C++ 为什么我的函数重载不如模板重载?
根据这个问题的第一个答案:,一个“非模板化(或“较少模板化”)重载比模板更可取” 如果删除C++ 为什么我的函数重载不如模板重载?,c++,templates,c++11,overload-resolution,C++,Templates,C++11,Overload Resolution,根据这个问题的第一个答案:,一个“非模板化(或“较少模板化”)重载比模板更可取” 如果删除调用的模板版本,则会得到预期的输出 在这种情况下,为什么我的调用重载没有选择第一个调用重载?lambdaf2的类型不是std::function,而是。因此,模板化的调用提供了更好的匹配。f1或f2都不是std::function类型。因此,模板是一个更好的匹配 如果您使用(作为示例) std::功能f3(f2); 呼叫(f3,“向世界致敬!”); 已使用您的调用。可以从函数或lambda表达式构造,但其
调用的模板版本
,则会得到预期的输出
在这种情况下,为什么我的
调用重载
没有选择第一个调用重载?lambdaf2
的类型不是std::function
,而是。因此,模板化的调用提供了更好的匹配。f1
或f2
都不是std::function
类型。因此,模板是一个更好的匹配
如果您使用(作为示例)
std::功能f3(f2);
呼叫(f3,“向世界致敬!”);
已使用您的调用。可以从函数或lambda表达式构造,但其类型与函数或lambda表达式不同。以下参数不完全匹配:
call(f1, "Hello World!");
call(f2, "Salut Monde !");
您可以使用铸造来完成此操作:
call(static_cast<std::function<void(std::string const&)>>(f1), "Hello World!");
call(static_cast<std::function<void(std::string const&)>>(f2), "Salut Monde !");
呼叫(静态播放(f1),“你好,世界!”);
呼叫(静态施法(f2),“向世界致敬!”;
f1和f2的类型不是
std::function
,需要用户定义的转换,因此选择模板版本
如果确实提供了与函数指针完全匹配的函数调用
,例如
void call (void(*callback)(std::string const&), const char *str)
它将被选择用于f1
注意:通过在lambda上添加一元
+
,在这种情况下,您还可以获得一个函数指针(您的捕获列表为空)
当您使用特定类型(函数的第二个参数)重载函数时(在本例中,当您使用特定参数调用函数时),模板函数将不会调用,因为您已经为特定类型编写了函数。除了模板函数调用的特定类型之外,编译器的任务是首先选择特定类型的参数,然后选择模板函数只有当参数类型完全匹配时,才首选非模板。在链接到的线程中,请注意
10
与非模板匹配,但10u
与模板匹配的示例;
call(f1, "Hello World!");
call(f2, "Salut Monde !");
call(static_cast<std::function<void(std::string const&)>>(f1), "Hello World!");
call(static_cast<std::function<void(std::string const&)>>(f2), "Salut Monde !");
void call (void(*callback)(std::string const&), const char *str)
auto f2 = +[](std::string const& str) -> void
// ^ unary +