簡體   English   中英

C ++候選模板傳遞lambda作為std :: function的參數時忽略錯誤

[英]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) {
  });
}

顯示的代碼嘗試推導出以下類型的TU

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很好地觀察了Ubar是如何不一致的。 但是在你的簡單例子中,為什么要經歷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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM