我试图在C++中创建一个映射
,字符串
作为键,泛型方法作为value
,但我不知道这是否可能。我想做这样的事情:
void foo(int x, int y)
{
//do something
}
void bar(std::string x, int y, int z)
{
//do something
}
void main()
{
std::map<std::string, "Any Method"> map;
map["foo"] = &foo; //store the methods in the map
map["bar"] = &bar;
map["foo"](1, 2); //call them with parameters I get at runtime
map["bar"]("Hello", 1, 2);
}
这可能吗?如果是,我如何实现这一点?
您可以在容器中键入-擦除函数类型,然后提供一个模板操作符()
。如果您弄错了,这将抛出std::bad_any_cast
。
N.B.由于类型擦除,您必须在调用站点指定完全匹配的参数,例如std::function
与std::function
不同,尽管两者都可以使用类似“hello”
这样的值调用。
#include <any>
#include <functional>
#include <map>
#include <string>
#include <iostream>
template<typename Ret>
struct AnyCallable
{
AnyCallable() {}
template<typename F>
AnyCallable(F&& fun) : AnyCallable(std::function(fun)) {}
template<typename ... Args>
AnyCallable(std::function<Ret(Args...)> fun) : m_any(fun) {}
template<typename ... Args>
Ret operator()(Args&& ... args)
{
return std::invoke(std::any_cast<std::function<Ret(Args...)>>(m_any), std::forward<Args>(args)...);
}
std::any m_any;
};
template<>
struct AnyCallable<void>
{
AnyCallable() {}
template<typename F>
AnyCallable(F&& fun) : AnyCallable(std::function(fun)) {}
template<typename ... Args>
AnyCallable(std::function<void(Args...)> fun) : m_any(fun) {}
template<typename ... Args>
void operator()(Args&& ... args)
{
std::invoke(std::any_cast<std::function<void(Args...)>>(m_any), std::forward<Args>(args)...);
}
std::any m_any;
};
void foo(int x, int y)
{
std::cout << "foo" << x << y << std::endl;
}
void bar(std::string x, int y, int z)
{
std::cout << "bar" << x << y << z << std::endl;
}
using namespace std::literals;
int main()
{
std::map<std::string, AnyCallable<void>> map;
map["foo"] = &foo; //store the methods in the map
map["bar"] = &bar;
map["foo"](1, 2); //call them with parameters I get at runtime
map["bar"]("Hello, std::string literal"s, 1, 2);
//map["bar"]("Hello, const char *literal", 1, 2); // bad_any_cast
map["bar"].operator()<std::string, int, int>("Hello, const char *literal", 1, 2); // explicit template parameters
return 0;
}
问题内容: 如何创建具有不同签名的函数片段?我尝试了下面的代码,但感觉有点黑。我们只是硬着头皮使用切片界面{}吗? 这仅仅是尝试对Golang做太多事情的一种情况吗? 问题答案: 请检查它,我不知道它是否想要什么。因为我不知道你到底想要什么。 在Go Playground 上检查 在这里,我有另一个使用反射调用的示例 在Go Playground 上检查
我会从我想达到的目标开始 意图 该软件在for循环中解析XML数据。处理数据的 for 循环将持续到 50(因为我得到了 50 个不同的结果)。我最初所做的是,-方法解析整个XML数据并将其保存到TextViews中并显示它。但现在我想添加一个启动画面,只要数据加载就会显示。 XML文件像任何其他普通XML文件一样构建,因此当我通过for循环时,键总是相同的,但值不同。 方法 我已经做的是创建一个
问题内容: 我有一个超类的方法: 在其子类之一中,我想执行以下操作: 但这是行不通的。问题是我有一个超类的引用,并且我想只在其中一个子类中调用此方法。 问题答案: 您不能在重写方法中更改类型参数的数量。对于您的情况,返回类型显然会覆盖失败。但是,即使返回类型相同,您的方法仍然不会被覆盖等效,因为您应该覆盖的方法中的类型参数更少。 从JLS- 方法签名 : 如果两个方法具有相同的名称和参数类型,则它
问题内容: 我有三个类:,和。 继承自和(按此顺序)。的构造特征和不同。如何调用两个父类的方法? 我在代码中的努力: 产生错误: 我发现此资源用不同的参数集解释了多重继承,但他们建议对所有参数使用和。我觉得这很丑陋,因为我无法从子类的构造函数调用中看到将哪些参数传递给父类。 问题答案: 千万 不能* 使用,除非你知道自己在做什么。第一个参数告诉它寻找下一个要使用的方法时要 跳过的 类。例如,将查看
我的应用程序只是一个看起来像这样的简单清单 ReactJS中的map函数有一些奇怪的行为。 每当我打印出来以检查值是否确实用console.log(todo.completed)更改时,它会在控制台中打印出正确的值,但随后我尝试打印出整个对象列表,突然它又回到了原来的状态。在本例中,我单击了选项1 这是我打印出常量updatedItems时的结果 我可以改变任何其他属性没有任何麻烦,我甚至可以设置
我有两个数据格式不同但值相同的表。 表一: 表二: 表1和表2之间的关系是多对一。此表的值与上面的日期格式相同。我现在的任务是映射这些表。我如何在ERD图中显示这些。我必须创建一个新表吗?