C++ `operator function_type()` 这样的事情可能吗?
我尝试编译 这个答案与如何在容器中存储具有不同签名的功能对象(例如:std::map) 我竞争(在我看来)提供了答案代码:
#include <functional>
#include <iostream>
#include <string>
#include <map>
class api {
//maps containing the different function pointers
std::map<std::string, void(*)()> voida;
std::map<std::string, int(*)(std::string, const int&)> stringcrint;
friend class apitemp;
public:
//api temp class
//given an api and a name, it converts to a function pointer
//depending on parameters used
class apitemp {
const std::string* n;
api* p;
public:
apitemp(const std::string* name, const api* parent)
: n(name), p(parent) {}
operator void(*)()()
{return p->void[*n];}
operator int(*)(std::string, const int&)()
{return p->stringcrint[*n];}
};
//insertion of new functions into appropriate maps
void insert(std::string name, void(*ptr)())
{voida[name]=ptr;}
void insert(std::string name, int(*ptr)(std::string, const int&))
{stringcrint[name]=ptr;}
//operator[] for the name gets halfway to the right function
apitemp operator[](std::string n) const {return apitemp(n, this);}
} myMap;
int hello_world(std::string name, const int & number )
{
name += "!";
std::cout << "Hello, " << name << std::endl;
return number;
}
int main() {
myMap.insert("my_method_hello", &hello_world );
// int a = myMap["my_method_hello"]("Tim", 25);
}
但是我在带有运算符的行上遇到了 12 个奇怪的错误:
错误 14 错误 C2665: 'api::apitemp::apitemp' :两个重载都无法转换所有参数类型 错误 4 错误 C2586:不正确的用户定义转换语法:非法间接寻址 错误 8 错误 C2586:不正确的用户定义转换语法:非法间接寻址 错误 9 错误 C2440:“初始化”:无法从“const api *”转换为“api *” 错误 10 错误 C2439:'api::apitemp::p':无法初始化成员 错误 13 错误 C2232: '->api::stringcrint' : 左操作数具有 '' 类型,请使用 '.' 错误 2 错误 C2091:函数返回函数 错误 3 错误 C2091:函数返回函数 错误 6 错误 C2091:函数返回函数 错误7错误C2091:函数返回函数 错误 11 错误 C2059:语法错误:“[” 错误 1 错误 C2059:语法错误:“*” 错误 5 错误 C2059:语法错误:“*” 错误 12 错误 C2039:“p”:不是“api”的成员
所以我想知道 - 如何让它编译?
更新:修复后(感谢hvd的回答)我得到了这个:
#include <boost/function.hpp>
#include <iostream>
#include <string>
#include <map>
template <typename T> struct identity { typedef T type; };
class api {
//maps containing the different function pointers
std::map<std::string, identity<void(*)()>::type > voida;
std::map<std::string, identity<int(*)(std::string, const int&)>::type > stringcrint;
friend class apitemp;
public:
//api temp class
//given an api and a name, it converts to a function pointer
//depending on parameters used
class apitemp {
std::string* n;
api* p;
public:
apitemp(std::string* name, api* parent)
: n(name), p(parent) {}
operator identity<void(*)()>::type()
{return p->voida[*n];}
operator identity<int(std::string, const int&)>::type*()
{return p->stringcrint[*n];}
};
//insertion of new functions into appropriate maps
void insert(std::string name, void(*ptr)())
{voida[name]=ptr;}
void insert(std::string name, int(*ptr)(std::string, const int&))
{stringcrint[name]=ptr;}
//operator[] for the name gets halfway to the right function
apitemp operator[](std::string n) {return apitemp(n, this);}
} myMap;
int hello_world(std::string name, const int & number )
{
name += "!";
std::cout << "Hello, " << name << std::endl;
return number;
}
int main() {
myMap.insert("my_method_hello", &hello_world );
int a = myMap["my_method_hello"]("Tim", 25);
}
然而有一个错误提示:
错误 1 错误 C2665: 'api::apitemp::apitemp' :2 个重载均无法转换所有参数类型
I try to compile this answer related to how to store functional objects with difrent signature in a container (eg: std::map) I compeated (seems to me) provided answer code:
#include <functional>
#include <iostream>
#include <string>
#include <map>
class api {
//maps containing the different function pointers
std::map<std::string, void(*)()> voida;
std::map<std::string, int(*)(std::string, const int&)> stringcrint;
friend class apitemp;
public:
//api temp class
//given an api and a name, it converts to a function pointer
//depending on parameters used
class apitemp {
const std::string* n;
api* p;
public:
apitemp(const std::string* name, const api* parent)
: n(name), p(parent) {}
operator void(*)()()
{return p->void[*n];}
operator int(*)(std::string, const int&)()
{return p->stringcrint[*n];}
};
//insertion of new functions into appropriate maps
void insert(std::string name, void(*ptr)())
{voida[name]=ptr;}
void insert(std::string name, int(*ptr)(std::string, const int&))
{stringcrint[name]=ptr;}
//operator[] for the name gets halfway to the right function
apitemp operator[](std::string n) const {return apitemp(n, this);}
} myMap;
int hello_world(std::string name, const int & number )
{
name += "!";
std::cout << "Hello, " << name << std::endl;
return number;
}
int main() {
myMap.insert("my_method_hello", &hello_world );
// int a = myMap["my_method_hello"]("Tim", 25);
}
But I get 12 strange errors on lines with operators:
Error 14 error C2665: 'api::apitemp::apitemp' : none of the 2 overloads could convert all the argument types Error 4 error C2586: incorrect user-defined conversion syntax : illegal indirections Error 8 error C2586: incorrect user-defined conversion syntax : illegal indirections Error 9 error C2440: 'initializing' : cannot convert from 'const api *' to 'api *' Error 10 error C2439: 'api::apitemp::p' : member could not be initialized Error 13 error C2232: '->api::stringcrint' : left operand has '' type, use '.' Error 2 error C2091: function returns function Error 3 error C2091: function returns function Error 6 error C2091: function returns function Error 7 error C2091: function returns function Error 11 error C2059: syntax error : '[' Error 1 error C2059: syntax error : '*' Error 5 error C2059: syntax error : '*' Error 12 error C2039: 'p' : is not a member of 'api'
So I wonder - how to make it compile?
Update: After fixes (thanks to hvd's answer ) I we got this:
#include <boost/function.hpp>
#include <iostream>
#include <string>
#include <map>
template <typename T> struct identity { typedef T type; };
class api {
//maps containing the different function pointers
std::map<std::string, identity<void(*)()>::type > voida;
std::map<std::string, identity<int(*)(std::string, const int&)>::type > stringcrint;
friend class apitemp;
public:
//api temp class
//given an api and a name, it converts to a function pointer
//depending on parameters used
class apitemp {
std::string* n;
api* p;
public:
apitemp(std::string* name, api* parent)
: n(name), p(parent) {}
operator identity<void(*)()>::type()
{return p->voida[*n];}
operator identity<int(std::string, const int&)>::type*()
{return p->stringcrint[*n];}
};
//insertion of new functions into appropriate maps
void insert(std::string name, void(*ptr)())
{voida[name]=ptr;}
void insert(std::string name, int(*ptr)(std::string, const int&))
{stringcrint[name]=ptr;}
//operator[] for the name gets halfway to the right function
apitemp operator[](std::string n) {return apitemp(n, this);}
} myMap;
int hello_world(std::string name, const int & number )
{
name += "!";
std::cout << "Hello, " << name << std::endl;
return number;
}
int main() {
myMap.insert("my_method_hello", &hello_world );
int a = myMap["my_method_hello"]("Tim", 25);
}
Yet one error stell stands:
Error 1 error C2665: 'api::apitemp::apitemp' : none of the 2 overloads could convert all the argument types
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以使用函数指针类型的转换运算符,但语法不允许您直接指定函数类型。您需要做的就是使用 typedef,我已将其包装在此处的模板中:
该代码还有其他几个错误,例如使用 const api* 初始化 api* 并传递 std::string 其中 std::需要字符串*。
You can have conversion operators to function pointer types, but the syntax does not let you specify the function type directly. All you need to do is use a typedef, which I've wrapped in a template here:
The code has several other errors, such as initializing an api* using a const api* and passing a std::string where a std::string* is wanted.
包含函数指针的声明是令人费解的,因此您可能首先尝试使用 typedef。
您还存在常量问题。 Map 的
operator[]
是一个修改操作,因此您必须使用map::find
来代替,或者使您自己的operator[]
非-const 也是如此。关于如何传递参数也不清楚。例如,为什么将 const 指针传递给字符串而不是 const 引用?为什么你有通过值传递字符串和通过 const 引用传递整数的函数(后者特别没有意义,因为复制整数更便宜)。
Declaration containing pointers to functions are mind-bending, so you might first try with a typedef.
You also have issues with constness. Map's
operator[]
is a modifying operation, so you either have to usemap::find
instead, or make your ownoperator[]
non-const too.There's also unclarity about how you pass parameters. E.g why pass a const pointer to a string rather than a const reference? Why you have functions passing strings by value and ints by const reference (the latter is particularly meaningless, since ints are cheaper to copy).
由于我为您编写了原始代码,因此我觉得有义务修复它:(
http://ideone.com/SXAPu
Since I wrote the orgional code for you I feel obliged to fix it :(
http://ideone.com/SXAPu