下面是一段C++代码,它编译得很好(gcc 10.1.0):-
#include <iostream>
#include <string>
#include <functional>
template <class T = std::string>
void foo(T src, std::function<void(T&& t)> completionFn)
{
completionFn(std::move(src));
}
int main(int argc, char *argv[])
{
foo<std::string>("hello", [] (auto && t) {
std::cout << t << std::endl;
});
return 0;
}
如果我修改main函数以移除对“foo”的调用中的模板参数,即使我有一个默认的模板参数,它也不再编译,而且我无法找出原因。
int main(int argc, char *argv[])
{
foo<>("hello", [] (auto && t) {
std::cout << t << std::endl;
});
return 0;
}
我可能遗漏了一些显而易见的东西。
以下是编译器输出:-
src/scanner_test.cpp: In function ‘int main(int, char**)’:
src/scanner_test.cpp:19:6: error: no matching function for call to ‘foo(const char [6], main(int, char**)::<lambda(auto:11&&)>)’
19 | });
| ^
src/scanner_test.cpp:10:6: note: candidate: ‘template<class T> void foo(T, std::function<void(T&&)>)’
10 | void foo(T src, std::function<void(T&& t)> completionFn)
| ^~~
src/scanner_test.cpp:10:6: note: template argument deduction/substitution failed:
src/scanner_test.cpp:19:6: note: ‘main(int, char**)::<lambda(auto:11&&)>’ is not derived from ‘std::function<void(T&&)>’
19 | });
我错过了什么? 谢啦! 如果这是个愚蠢的问题,请原谅。
只有在无法从上下文确定模板时,才使用默认模板参数。 在给定的上下文foo<>>(“hello”,...)
中,模板T被确定为const char[6]
(如错误消息中所给)。 对于函数,与函数中的实际参数相关的模板参数总是如此。
你可能在寻找的解决方案是:
#include <iostream>
#include <string>
#include <functional>
template <class T>
void foo(T src, std::function<void(std::string&& t)> completionFn)
{
//NOTE cast here to std::string, ensures we always have an std::string
completionFn(std::move((std::string&)src));
}
int main(int argc, char *argv[])
{
foo("hello", [] (std::string&& t) {
std::cout << t << std::endl;
});
return 0;
}