![](/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.