重载 C++函数映射容器中的函数返回类型:自动推导失败并出现编译器错误
我有像 this 这样的简单类(其行为类似于 Boost::overload,但其中有命名函数(我用它来简化\缩小反射\内省目的))。输入参数的多个返回类型存在问题(编译器错误 3066)。我的代码:
#include <iostream>
#include <string>
#include <map>
#include <vector>
template < class T0, class T1 >
class my_map {
typedef T0 type_0;
typedef T1 type_1;
std::map < std::string, type_0 * >T0_var;
std::map < std::string, type_1 * >T1_var;
friend class apitemp;
public:
my_map(int meaningless0 = 42, int meaningless1 = 42) {}
class apitemp {
std::string n_;
my_map *p;
public:
apitemp(std::string name_, my_map * parent):n_(name_), p(parent) {}
operator type_0 *() {
return p->T0_var[n_];
}
operator type_1 *() {
return p->T1_var[n_];
}
};
void insert(std::string name, type_0 * ptr) {
T0_var[name] = ptr;
}
void insert(std::string name, type_1 * ptr) {
T1_var[name] = ptr;
}
apitemp operator[] (std::string n_) {
return apitemp(n_, this);
}
};
template<class out, class in1, class in2>
out hello_world(in1 name, in2 number )
{
name += "!";
std::cout << "Hello, " << name << std::endl;
return number;
}
template<class in1, class in2>
std::string hello_world(in1 name, in2 number )
{
name += "!";
std::cout << "Hello, " << name << std::endl;
return std::string("Yep, we can!");
}
int main() {
int a = hello_world<int, std::string, const int &>("Tim", 25);
std::string b = hello_world<std::string, const int &>("Tim", 25);
my_map<int(std::string, const int &), std::string(std::string, const int &)> myMap;
myMap.insert("my_method_hello", &hello_world<int, std::string, const int &> );
myMap.insert("my_method_hello2", &hello_world<std::string, const int &> );
//int a = myMap["my_method_hello"]("Tim", 25); // error C3066: there are multiple ways that an object of this type can be called with these arguments
//std::string b = myMap["my_method_hello2"]("Tim", 25); // // error C3066: there are multiple ways that an object of this type can be called with these arguments
std::cin.get();
}
如何向其API引入多个返回类型函数? API用户是否可以以不可见的方式实现?或者至少有一些让 API 用户感到不安的东西,比如
int a = myMap["my_method_hello"]("Tim", 25)::int;
std::string b = myMap["my_method_hello2"]("Tim", 25)::string;
?
I have simple class like this (which behaves like Boost::overload, but has named functions in it ( I use it for simplified\minified reflection\introspection purposes) ). It has problems with multiple return types for input arguments (compiler error 3066). My code:
#include <iostream>
#include <string>
#include <map>
#include <vector>
template < class T0, class T1 >
class my_map {
typedef T0 type_0;
typedef T1 type_1;
std::map < std::string, type_0 * >T0_var;
std::map < std::string, type_1 * >T1_var;
friend class apitemp;
public:
my_map(int meaningless0 = 42, int meaningless1 = 42) {}
class apitemp {
std::string n_;
my_map *p;
public:
apitemp(std::string name_, my_map * parent):n_(name_), p(parent) {}
operator type_0 *() {
return p->T0_var[n_];
}
operator type_1 *() {
return p->T1_var[n_];
}
};
void insert(std::string name, type_0 * ptr) {
T0_var[name] = ptr;
}
void insert(std::string name, type_1 * ptr) {
T1_var[name] = ptr;
}
apitemp operator[] (std::string n_) {
return apitemp(n_, this);
}
};
template<class out, class in1, class in2>
out hello_world(in1 name, in2 number )
{
name += "!";
std::cout << "Hello, " << name << std::endl;
return number;
}
template<class in1, class in2>
std::string hello_world(in1 name, in2 number )
{
name += "!";
std::cout << "Hello, " << name << std::endl;
return std::string("Yep, we can!");
}
int main() {
int a = hello_world<int, std::string, const int &>("Tim", 25);
std::string b = hello_world<std::string, const int &>("Tim", 25);
my_map<int(std::string, const int &), std::string(std::string, const int &)> myMap;
myMap.insert("my_method_hello", &hello_world<int, std::string, const int &> );
myMap.insert("my_method_hello2", &hello_world<std::string, const int &> );
//int a = myMap["my_method_hello"]("Tim", 25); // error C3066: there are multiple ways that an object of this type can be called with these arguments
//std::string b = myMap["my_method_hello2"]("Tim", 25); // // error C3066: there are multiple ways that an object of this type can be called with these arguments
std::cin.get();
}
How to introduce to its API multiple return type functions? Is it possible in invisiable for API user way? Or at least with something API user disturbing like
int a = myMap["my_method_hello"]("Tim", 25)::int;
std::string b = myMap["my_method_hello2"]("Tim", 25)::string;
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
一种方法是让
myMap["my_method_hello"]("Tim", 25)
返回一个定义operator int()
,operator 的代理对象std::string()
等您希望它返回的每种类型。另一种方法是让代理对象为每种类型定义显式的.asInt()
、.asString()
方法。如果目标类型在源代码中不明确(例如,如果将结果传递给函数),则重载运算符技术可能会令人困惑。同样,代理类型可能会混淆您传递给它的模板函数,并且如果候选集包含同时采用
int
和std 的函数,则将无法轻松选择重载函数: :string
(或代理自动转换为的其他类型。因此,除了任何运算符之外,我建议提供.asInt()
等函数。您还可以拼写
.asInt()
等像templateas()
这样的函数并使用显式专门化来定义新的转换,唯一的缺点是源代码变得有点难以阅读。One way to do this is to have
myMap["my_method_hello"]("Tim", 25)
return a proxy object that definesoperator int()
,operator std::string()
, etc for each type you want it to return. Another way is to have the proxy object define explicit.asInt()
,.asString()
methods for each type.The overloaded operator technique can get confusing if the target type isn't explicit in the source code (for example, if you're passing the result to a function). Similarly, the proxy type is likely to confuse template functions you pass it to, and won't be able to easily select an overloaded function if the candidate set includes functions taking both
int
andstd::string
(or other types the proxy auto-converts to. So I recommend providing the.asInt()
, etc. functions in addition to any operators.You can also spell the
.asInt()
, etc. functions liketemplate<typename T> as()
and use explicit specialization to define new conversions. The only downside to this is that the source code gets a bit harder to read.