[英]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.