![](/img/trans.png)
[英]C++ - Why is this candidate template with a function pointer parameter ignored?
[英]C++ Candidate Template Ignored error when passing lambda as argument for std::function
这是我在C ++中遇到的模板问题的一般骨架版本。 我无法弄清楚如何在从foo
调用时将bar
函数模板识别为合理的候选者。
#include <iostream>
#include <cstdlib>
#include <unordered_map>
template<class T>
std::unordered_map<std::string, T> getStr2TMap() {
return {}; // suppose logic here is a bit more involved
}
template<class T>
std::unordered_map<int, T> getInt2TMap() {
return {}; // suppose logic here is a bit more involved
}
template<class U, class T>
void bar(
const std::function<void (std::unordered_map<U, T>&&)>& baz
) {
if (rand() % 2 > 0) {
baz(getInt2TMap<T>());
} else {
baz(getStr2TMap<T>());
}
}
template<class T>
void foo(
const std::unordered_map<std::string, T>& map1
) {
bar([&map1](auto&& map2) {
// do some things with map1 and map2
});
}
int main() {
std::unordered_map<std::string, int> myMap;
foo<int>(myMap);
}
编辑
很多简化版本的代码,同样的错误。 我正在寻找上述版本的解决方案,而不是这个。
#include <iostream>
#include <functional>
#include <unordered_map>
template<class T>
void foo(
const std::function<void (std::unordered_map<int, T>&&)>& bar
) {
std::unordered_map<int, T> myMap;
bar(myMap);
}
int main() {
foo([](auto&& m) {
});
}
显示的代码尝试推导出以下类型的T
和U
std::function<void (std::unordered_map<U, T>&&)>
推导尝试是针对传递给模板函数的lambda参数:
[&map1](auto&& map2) {}
问题是lambda不是某种std::function
。 它是一个:
...唯一未命名的非联合非聚合类类型的临时对象,称为“闭包”类型,...
( 引用 )
换句话说,lambda对象是一个类的实例,其中operator()
执行lambda代码(捕获的对象被变换为未命名类的成员)。 因此,由于它不是std::function
,因此无法从中推导出std::function
的类型。
因为它是一个可调用类型,所以它可以转换为std::function
,但是:
bar(static_cast<std::function<void(std::unordered_map<std::string, T> &&)>>
([&map1](auto&& map2) {
// do some things with map1 and map2
}));
}
这将获得bar()
模板功能的识别。
但是显示的代码仍然存在第二个问题:
if (rand() % 2 > 0) {
baz(getInt2TMap<T>());
} else {
baz(getStr2TMap<T>());
}
根据骰子的滚动,代码将尝试传递无序的字符串映射,或者将无序的int映射传递给baz()
。
那......不会起作用。 在游戏的这个阶段, baz
是某种std::function
。 它不是模板。 因此,它只能采用一种类型的参数。
如果你添加static_cast
,并使bar()
a:
baz(getStr2TMap<T>());
为了匹配调用者传递无序的字符串映射这一事实,生成的代码应该编译。
你的bar()
里面发生了什么bar()
是一个单独的问题。 使用static_cast
回答了如何识别候选模板bar
。
Sam很好地观察了U
在bar
是如何不一致的。 但是在你的简单例子中,为什么要经历const std::function<void (std::unordered_map<int, T>&&)>&
所有麻烦const std::function<void (std::unordered_map<int, T>&&)>&
何时你可以写:
#include <iostream>
#include <functional>
#include <unordered_map>
template<class T, class Func>
void foo(
Func bar
) {
std::unordered_map<int, T> myMap;
bar(myMap);
}
int main() {
// needs the hint for T, since it isn't used anywhere
foo<int>([](auto&& m) {
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.