简体   繁体   English

如何将 map 不同的 function 签名转换为相同的 std::map?

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

I had some issues which were pointed in the comments, so this is my new minimal reproducible code sample;我有一些在评论中指出的问题,所以这是我新的最小可重现代码示例;

#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;
}

Given this, I can do what I intend when I static cast foo into baz like in second way.鉴于此,当我 static 像第二种方式一样将foo转换为baz时,我可以做我想做的事情。 But why can't it be done in the first way?但是为什么不能以第一种方式完成呢?

What I ask, is that;我要问的是;

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

I thought these two would be equal, but apparently when it comes to static cast, they're not.我认为这两者是相等的,但显然当谈到 static 演员时,他们不是。
Why so?为什么这样?

Also, are these same or not?另外,这些是否相同?

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

And why?为什么?

If I understand the comments correctly, the std::map<Key, Value> is only part of the problem.如果我正确理解评论,则std::map<Key, Value>只是问题的一部分。 You first need the Value part - what C++ type can hold the overload set of f ?您首先需要Value部分 - 什么 C++ 类型可以容纳f的重载集?

Jarod's comment is right: You basically need [](auto... args){ return foo(args...)}; Jarod 的评论是对的:你基本上需要[](auto... args){ return foo(args...)}; . . This is a single lambda object, with an overloaded operator() .这是单个 lambda object,带有重载的operator() Each overload of operator() selects one of your foo() overloads. operator()的每个重载都会选择您的foo()重载之一。

This then shows the ultimate problem.这说明了最终的问题。 [](auto... args){ return bar(args...)}; is another lambda, with a different type, so it can't go in the same std::map<Key, Value> .是另一个 lambda,具有不同的类型,因此它不能 go 在同一个std::map<Key, Value>中。

That's really no surprise.这真的不足为奇。 When the compiler sees baz["foo"](qux) , it needs Value::operator(std::string) .当编译器看到baz["foo"](qux)时,它需要Value::operator(std::string) That can be a template instantiation, but an instantiation cannot happen at runtime.这可以是模板实例化,但实例化不能在运行时发生。 So Value can't depend on "foo" .所以Value不能依赖于"foo" C++ simply does not have run-time overloading, that is not how the language works. C++ 根本没有运行时重载,这不是语言的工作方式。

@JesperJuhl may have a point that this is an XY problem. @JesperJuhl 可能认为这是一个 XY 问题。 What if you had foo(std::variant<int, std::string, std::vector<int>>) ?如果你有foo(std::variant<int, std::string, std::vector<int>>)怎么办? This is not an overload set;这不是一个重载集; this is a single function.这是单个 function。 Behind the scenes, it can dispatch to foo_impl(...) in any way you like.在幕后,它可以以任何你喜欢的方式分派给foo_impl(...)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM