C++ 相同函数参数不同返回类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14840173/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++ same function parameters with different return type
提问by Josh Johnson
I need to find some way to mock an overload of a function return type in C++.
我需要找到某种方法来模拟 C++ 中函数返回类型的重载。
I know that there isn't a way to do that directly, but I'm hoping there's some out-of-the-box way around it. We're creating an API for users to work under, and they'll be passing in a data string that retrieves a value based on the string information. Those values are different types. In essence, we would like to let them do:
我知道没有办法直接做到这一点,但我希望有一些开箱即用的方法。我们正在创建一个供用户使用的 API,他们将传入一个数据字符串,该字符串根据字符串信息检索一个值。这些值是不同的类型。本质上,我们想让他们做:
int = RetrieveValue(dataString1);
double = RetrieveValue(dataString2);
// Obviously, since they don't know the type, they wouldn't use int =.... It would be:
AnotherFunction(RetrieveValue(dataString1)); // param of type int
AnotherFunction(RetrieveValue(dataString2)); // param of type double
But that doesn't work in C++ (obviously). Right now, we're having it set up so that they call:
但这在 C++ 中不起作用(显然)。现在,我们正在设置它,以便他们调用:
int = RetrieveValueInt(dataString1);
double = RetrieveValueDouble(dataString2);
However, we don't want them to need to know what the type of their data string is.
但是,我们不希望他们需要知道他们的数据字符串的类型是什么。
Unfortunately, we're not allowed to use external libraries, so no using Boost.
不幸的是,我们不允许使用外部库,所以没有使用 Boost。
Are there any ways we can get around this?
有什么办法可以解决这个问题吗?
Just to clarify, I understand that C++ can't natively do it. But there must be some way to get around it. For example, I thought about doing RetrieveValue(dataString1, GetType(dataString1)). That doesn't really fix anything, because GetType also can only have one return type. But I need something like that.
澄清一下,我知道 C++ 本身无法做到这一点。但必须有办法绕过它。例如,我想过做 RetrieveValue(dataString1, GetType(dataString1))。这并不能真正解决任何问题,因为 GetType 也只能有一种返回类型。但我需要这样的东西。
I understand that this question has been asked before, but in a different sense. I can't use any of the obvious answers. I need something completely out-of-the-box for it to be useful to me, which was not the case with any of the answers in the other question asked.
我知道以前有人问过这个问题,但意义不同。我不能使用任何明显的答案。我需要一些完全开箱即用的东西才能对我有用,而其他问题中的任何答案都不是这种情况。
回答by Nawaz
You've to start with this:
你必须从这个开始:
template<typename T>
T RetrieveValue(std::string key)
{
//get value and convert into T and return it
}
To support this function, you've to work a bit more, in order to convert the value into the type T
. One easy way to convert value could be this:
要支持此功能,您必须做更多工作,以便将值转换为类型T
。转换值的一种简单方法可能是:
template<typename T>
T RetrieveValue(std::string key)
{
//get value
std::string value = get_value(key, etc);
std::stringstream ss(value);
T convertedValue;
if ( ss >> convertedValue ) return convertedValue;
else throw std::runtime_error("conversion failed");
}
Note that you still have to call this function as:
请注意,您仍然必须将此函数调用为:
int x = RetrieveValue<int>(key);
You could avoid mentioning int
twice, if you could do this instead:
int
如果您可以这样做,则可以避免提及两次:
Value RetrieveValue(std::string key)
{
//get value
std::string value = get_value(key, etc);
return { value };
}
where Value
is implemented as:
其中Value
实现为:
struct Value
{
std::string _value;
template<typename T>
operator T() const //implicitly convert into T
{
std::stringstream ss(_value);
T convertedValue;
if ( ss >> convertedValue ) return convertedValue;
else throw std::runtime_error("conversion failed");
}
}
Then you could write this:
那么你可以这样写:
int x = RetrieveValue(key1);
double y = RetrieveValue(key2);
which is which you want, right?
这是你想要的,对吧?
回答by Walter
If the datastrings are compile-time constants (as said in answering my comment), you could use some template magic to do the job. An even simpler option is to not use strings at all but some data types which allow you then to overload on argument.
如果数据字符串是编译时常量(如在回答我的评论中所说),您可以使用一些模板魔术来完成这项工作。一个更简单的选择是根本不使用字符串,而是使用一些允许您重载参数的数据类型。
struct retrieve_int {} as_int;
struct retrieve_double {} as_double;
int RetrieveValue(retrieve_int) { return 3; }
double RetrieveValue(retrieve_double) { return 7.0; }
auto x = RetrieveValue(as_int); // x is int
auto y = RetrieveValue(as_double); // y is double
回答by Walter
The only sane way to do this is to move the return value to the parameters.
唯一明智的方法是将返回值移动到参数中。
void retrieve_value(std::string s, double& p);
void retrieve_value(std::string s, int& p);
<...>
double x;
retrieve_value(data_string1, x);
int y;
retrieve_value(data_string2, y);
回答by Rob?
Whether it is an overload or a specialization, you'll need the information to be in the function signature. You could pass the variable in as an unused 2nd argument:
无论是重载还是特化,您都需要函数签名中的信息。您可以将变量作为未使用的第二个参数传递:
int RetrieveValue(const std::string& s, const int&) {
return atoi(s.c_str());
}
double RetrieveValue(const std::string& s, const double&) {
return atof(s.c_str());
}
int i = RetrieveValue(dataString1, i);
double d = RetrieveValue(dataString2, d);
回答by HackyStack
If you know your value can never be something like zero or negative, just return a struct holding int and double and zero out the one you don't need...
如果您知道您的值永远不会是零或负数,只需返回一个包含 int 和 double 的结构体,然后将您不需要的值归零...
It's a cheap and dirty, but easy way...
这是一种既便宜又脏,但简单的方法......
struct MyStruct{
int myInt;
double myDouble;
};
MyStruct MyFunction(){
}
回答by Simon
As an alternative to the template solution, you can have the function return a reference or a pointer to a class, then create subclasses of that class to contain the different data types that you'd like to return. RetrieveValue
would then return a reference to the appropriate subclass.
作为模板解决方案的替代方案,您可以让函数返回一个类的引用或指针,然后创建该类的子类以包含您想要返回的不同数据类型。RetrieveValue
然后将返回对适当子类的引用。
That would then let the user pass the returned object to other functions without knowing which subclass it belonged to.
这会让用户在不知道它属于哪个子类的情况下将返回的对象传递给其他函数。
The problem in this case would then become one of memory management -- choosing which function allocates the returned object and which function deletes it, and when, in such a way that we avoid memory leaks.
在这种情况下,问题将成为内存管理之一——选择哪个函数分配返回的对象,哪个函数删除它,以及何时以这样的方式避免内存泄漏。
回答by Twiltie
Unfortunately there is no way to overload the function return type see this answer Overloading by return type
不幸的是,无法重载函数返回类型,请参阅此答案 按返回类型重载
回答by Ricardo Ortega Maga?a
int a=itoa(retrieveValue(dataString));
double a=ftoa(retrieveValue(dataString));
both return a string.
都返回一个字符串。
回答by Seth Carnegie
Since you used an example that wasn't really what you wanted, you threw everyone off a bit.
由于您使用的示例并不是您真正想要的,因此您让每个人都有些失望。
The setup you really have (calling a function with the return value of this function whose return type is unknowable) will not work because function calls are resolved at compile time.
您真正拥有的设置(使用返回类型未知的函数的返回值调用函数)将不起作用,因为函数调用是在编译时解析的。
You are then restricted to a runtime solution. I recommend the visitor pattern, and you'll have to change your design substantially to allow for this change. There isn't really another way to do it that I can see.
然后,您只能使用运行时解决方案。我推荐访问者模式,您必须大幅更改您的设计以允许此更改。我真的没有其他方法可以做到这一点。