簡體   English   中英

如何將 map 不同的 function 簽名轉換為相同的 std::map?

[英]How to map different function signatures into the same std::map?

我有一些在評論中指出的問題,所以這是我新的最小可重現代碼示例;

#include <functional>
#include <iostream>
#include <vector>
#include <map>
std::string foo(int bar)
{
    return std::to_string(bar); 
}
std::string foo(std::vector<int> bar)
{
    int baz;
    //process
    return foo(baz);
}
std::string foo(std::string bar)
{
    std::vector<int> baz;
    //process
    return foo(baz);
}
int main()
{
    std::map<std::string,std::function<std::string(std::string)>> baz;
    //error baz["foo"]=static_cast<std::function<std::string(std::string)>>(&foo);
    /*working*/baz["foo"]=static_cast<std::string(*)(std::string)>(&foo);
    std::string qux;
    std::cout<<baz["foo"](qux)<<std::endl;
}

鑒於此,當我 static 像第二種方式一樣將foo轉換為baz時,我可以做我想做的事情。 但是為什么不能以第一種方式完成呢?

我要問的是;

(<std::function<std::string(std::string)> == std::string(*)(std::string))

我認為這兩者是相等的,但顯然當談到 static 演員時,他們不是。
為什么這樣?

另外,這些是否相同?

std::map<std::string,std::function<std::string(std::string)>> baz;
std::map<std::string,std::string(*)(std::string)> baz;

為什么?

如果我正確理解評論,則std::map<Key, Value>只是問題的一部分。 您首先需要Value部分 - 什么 C++ 類型可以容納f的重載集?

Jarod 的評論是對的:你基本上需要[](auto... args){ return foo(args...)}; . 這是單個 lambda object,帶有重載的operator() operator()的每個重載都會選擇您的foo()重載之一。

這說明了最終的問題。 [](auto... args){ return bar(args...)}; 是另一個 lambda,具有不同的類型,因此它不能 go 在同一個std::map<Key, Value>中。

這真的不足為奇。 當編譯器看到baz["foo"](qux)時,它需要Value::operator(std::string) 這可以是模板實例化,但實例化不能在運行時發生。 所以Value不能依賴於"foo" C++ 根本沒有運行時重載,這不是語言的工作方式。

@JesperJuhl 可能認為這是一個 XY 問題。 如果你有foo(std::variant<int, std::string, std::vector<int>>)怎么辦? 這不是一個重載集; 這是單個 function。 在幕后,它可以以任何你喜歡的方式分派給foo_impl(...)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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