C++ Can重载函数';不同的变体可以映射到同一个映射中吗? #包括 #包括 使用名称空间std; 字符串读取(字符串a){返回“abc”;} 无效读取(浮点a){} bool read(int a){return true;} int main() { 地图f1; 图f2; 地图f3; f1[“读取”]=读取; f2[“读取”]=读取; f3[“读取”]=读取; 字符串t,u; 而(1) { cin>>t>>u; 如果(!f1.count(t)| |!f2.count(t)| |!f3.count(t))不能将一组重载作为映射中的一个元素。您可以在映射中放置一些具有重载成员函数的对象,尽管这也没有帮助,因为您希望映射中的元素具有不同的重载
下一个问题是,当参数来自用户输入时,您需要在调用它之前决定要调用的重载。通常您让编译器根据参数来决定,但这里您需要将用户输入解析为参数的类型 此外,映射中的元素必须都是相同的类型。该类型应提供一个接口,允许您以方便的方式调用函数 换句话说,简单的方法是将函数包装成始终采用相同参数并始终返回相同参数的内容,然后将其放入映射中。我建议使用C++ Can重载函数';不同的变体可以映射到同一个映射中吗? #包括 #包括 使用名称空间std; 字符串读取(字符串a){返回“abc”;} 无效读取(浮点a){} bool read(int a){return true;} int main() { 地图f1; 图f2; 地图f3; f1[“读取”]=读取; f2[“读取”]=读取; f3[“读取”]=读取; 字符串t,u; 而(1) { cin>>t>>u; 如果(!f1.count(t)| |!f2.count(t)| |!f3.count(t))不能将一组重载作为映射中的一个元素。您可以在映射中放置一些具有重载成员函数的对象,尽管这也没有帮助,因为您希望映射中的元素具有不同的重载,c++,C++,下一个问题是,当参数来自用户输入时,您需要在调用它之前决定要调用的重载。通常您让编译器根据参数来决定,但这里您需要将用户输入解析为参数的类型 此外,映射中的元素必须都是相同的类型。该类型应提供一个接口,允许您以方便的方式调用函数 换句话说,简单的方法是将函数包装成始终采用相同参数并始终返回相同参数的内容,然后将其放入映射中。我建议使用std::istream进行输入,使用std::ostream进行输出: #include <iostream> #include <map>
std::istream
进行输入,使用std::ostream
进行输出:
#include <iostream>
#include <map>
using namespace std;
string read(string a){return "abc";}
void read(float a){}
bool read(int a){return true;}
int main()
{
map<string,string(*)(string)> f1;
map<string,void(*)(float)> f2;
map<string,bool(*)(int)> f3;
f1["read"]=read;
f2["read"]=read;
f3["read"]=read;
string t,u;
while(1)
{
cin>>t>>u;
if(!f1.count(t)||!f2.count(t)||!f3.count(t)) cout<<"Unknown command!\n";
else cout<<f1[t](u);
}
}
PS:我想你不会坚持重载解析可以通过推断要放入映射中的函数的参数和返回类型在某种程度上实现自动化,尽管它不适用于重载(这将是一个不同的问题)。我根据@idclev 463035818的最初建议处理了这个问题,多亏了他们。 这是我最近的样品
abc
#包括
#包括
#包括
使用名称空间std;
typedef字符串(*func)(字符串);
结构演示
{
地图f;
}g;
字符串read_p(字符串)、read(字符串)、read(int);
int main()
{
g、 f[“读取”]=读取;
而(1)
{
coutQt framework使用类似于您所建议的方法来处理事件。所述框架将所有插槽函数指针强制转换为void*
,并在使用前强制转换。该框架的代码生成由元对象编译器完成
我怀疑这是一种实现定义的行为,在大多数平台上都是可行的,只要您正确跟踪哪些指针指向哪个函数。最近,它们的设计变得更加复杂,以支持处理程序的lambda表达式。一旦函数出现在映射中,您将如何使用它们?在某一点上,您需要知道是什么它的功能类型is@idclev463035818我打算将u
从string
转换为int
或float
在无限while
循环中。因此,这不会改变或解决我的问题。可能不会改变你的问题,但会影响解决方案。你能提供多一点上下文吗?我的意思是在你的例子中e> u
始终是一个std::string
传递给f1[t]
,当它可以是不同类型的函数时,您希望如何调用f[t]
呢?我试图传达的是,将函数放在映射中是“简单的”部分,困难的部分是,一旦它们出现在地图中,您仍然需要在调用代码中决定是调用f1[t](u);
还是f1[t](u,second_参数)
因此,让所有函数都以字符串作为参数并让函数进行解析会更简单。我仍在试图理解您打算如何使用该映射。此外,对于返回值,您需要知道它是什么,否则您无法正确使用该函数。感谢您的时间,我将使用这种方式。哦……结果不是这样hatstd::function
从C++11开始就受到支持,但我的编译器使用的是C++03。我需要找到另一种方法,但我已经理解了您处理这种情况的方法,我将调整一些代码以使用C++03的方法来完成它。@Xemdocia lambdas总是可以用手写的functor代替,实际上,std::function
只是出于懒散我在这里不推荐(不需要)。您可以编写一个基类,并在映射中放置一些指向继承对象实例的智能指针。这在C++03中是可能的,但最终您将编写大量的样板文件,因此我建议升级到C++11。也许您只需将-std=C++11
标志传递给您的编译器谢谢;但是我的编译器和我的pc都过时了。因此,我建议您升级到C++11说,我根据你的第一个建议写了一个代码,并将其添加为新的答案。
abc
#include <iostream>
#include <fstream>
#include <map>
using namespace std;
typedef string (*func)(string);
struct demo
{
map<string,func> f;
}g;
string read_p(string),read(string),read(int);
int main()
{
g.f["read"]=read_p;
while(1)
{
cout<<">>";
string t;
getline(cin,t);
size_t found=t.find(" ");
if(found==-1){if(!g.f.count(t)) cout<<"Unrecognized command!\n"; else cout<<g.f[t](t);}
else
{
string a=t.substr(0,found),b=t.substr(found+1,t.length()-found);
if(!g.f.count(a)) cout<<"Unrecognized long command!\n"; else cout<<g.f[a](b);
}
}
return 0;
}
string read_p(string c)
{
if(c=="read") return "Read what?\n";
else if(c=="story") return read(c);
else if(c.substr(0,4)!="page") return "Can't read that!\n";
else
{
size_t found=c.find_first_of("0123456789");
if(found==-1) return "Choose a page!\n";
else
{
int d=atoi((c.substr(found,2)).c_str());
return read(d);
}
}
}
string read(string a)
{
ifstream counter("game.txt",ifstream::in);
string x3;
int line=0;
while(counter.good()){getline(counter,x3); line++;}
counter.close();
string x1[line],x2="\"";
ifstream x("game.txt",ifstream::in);
for(int i=0; i<line; i++)
{
getline(x,x1[i]);
x1[i].erase(0,3);
x2.append(x1[i]+"\n");
}
x.close();
x2.erase(x2.length()-2,2);
x2.append("\"\n");
return x2;
}
string read(int a)
{
if(a<14||a>18) return "Choose another page!\n";
int page=-1;
ifstream x("game.txt",ifstream::in);
string x1;
while(a!=page){getline(x,x1); page=atoi((x1.substr(0,2)).c_str());}
x1.erase(0,3);
x1.insert(0,"\"");
x1.append("\"\n");
return x1;
}