为什么我的函数重载不优先于我的模板化重载
Why is my function overload not preferred over my templated one?
根据这个问题的第一个答案:函数模板重载,"非模板化(或"模板化较少")重载比模板更可取"。
#include <iostream>
#include <string>
#include <functional>
void f1(std::string const& str) {
std::cout << "f1 " << str << "n";
}
template <typename Callback, typename... InputArgs>
void call(Callback callback, InputArgs ...args) {
callback(args...);
}
void call(std::function<void(std::string const&)> callback, const char *str) {
std::cout << "custom call: ";
callback(str);
}
int main() {
auto f2 = [](std::string const& str) -> void {
std::cout << "f2 " << str << "n";
};
call(f1, "Hello World!");
call(f2, "Salut Monde !");
return 0;
}
据我了解,call
的第二个定义是"非模板化的",因此当我做call(f1, "1")
或call(f2, "2")
时,应该选择第一个定义而不是第一个定义。
事实并非如此,我得到以下输出:
f1 Hello World!
f2 Salut Monde !
如果我删除call
的模板化版本,我会得到预期的输出。
在这种情况下,为什么我的超载call
没有选择第一个?
f1
和 f2
的类型不std::function
,需要用户定义的转换,因此选择模板版本。
如果您确实提供了与函数指针完全匹配的函数call
,例如;
void call (void(*callback)(std::string const&), const char *str)
它将被选为f1
.
注意:通过在 lambda 上添加一元+
,在这种情况下您还可以获得一个函数指针(您的捕获列表为空)...
auto f2 = +[](std::string const& str) -> void
// ^ unary +
lambda f2
的类型不是std::function<void(std::string const&)>
,它是一个编译器生成的类型。因此,模板化call
提供了更好的匹配。
f1
和 f2
都不属于 std::function<...>
型。因此,模板是更好的匹配。
如果您使用(作为示例)
std::function<void(std::string const&)> f3(f2);
call(f3, "Salut Monde !");
您的呼叫已被使用。
std::function 可以从函数或 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 !");
住
当您使用特定类型(函数的第二个参数)重载函数时,在这种情况下,当您使用特定参数调用函数时,模板函数将不会调用,因为您已经为特定类型编写了函数。 除了模板函数调用的特定类型外,编译器作业首先选择特定类型参数,然后选择模板函数
相关文章:
- 为什么我可以在不重载 "=" 运算符的情况下将一个对象分配给另一个对象?
- 我的运算符重载是否有效<<(流插入)左操作数不是 ostream
- 为什么我的运算符 + 重载尽管是通过引用传递的,但仍调用我的复制构造函数?
- 如何为我的类实现/重载二进制运算符
- 什么时候可以使用常量装饰调用我的重载函数?
- 我的运算符重载没有在我的 int main 中返回?
- 如何让我的重载<<运算符打印出我的函数?
- c++运算符重载-我实际返回的操作数类型是什么
- 我的重载运算符 == 中的 C++ 参数太少
- 我的重载函数有什么问题?
- 如何重载运算符<<显示我的列表
- 我的移动分配操作程序重载的分段错误
- 为什么我的重载 + 运算符在返回时会产生"Invalid address specified to RtlValidateHeap"错误?
- 无法使用"enable_if"和"is_base_of"将模板函数"operator+"的重载限制到我的类层次结构
- 我的重载后增量方法无法按预期工作。为什么?
- 为什么我的重载运算符+在向自身添加变量时会在返回时使"this"未初始化?
- 我的运算符重载友元函数无法理解模板类型 T 的问题
- 运算符重载如何工作,为什么在我的情况下不起作用?
- C++正在重载我的重载运算符
- 有人可以指出为什么我的变量无法识别以及为什么我不能重载我的运算符吗