C ++ same functional parameters with different return type

I need to find a way to recompose overloading the return type of a function in C ++.

I know that there is no direct way to do this, but I hope that there will be some simple way. We are creating an API for users to work with and they will pass a data string that retrieves a value based on the string information. These values ​​are different types. Essentially, we would like to let them:

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 this does not work in C ++ (obviously). Right now, we are setting it up so that they call:

 int = RetrieveValueInt(dataString1); double = RetrieveValueDouble(dataString2); 

However, we do not want them to know what type of data row they are.

Unfortunately, we are not allowed to use external libraries, so without using Boost.

Are there any ways around this?

Just to clarify, I understand that C ++ cannot initially do this. But there must be some way around this. For example, I was thinking of doing RetrieveValue (dataString1, GetType (dataString1)). This does not fix anything, because GetType can also have only one return type. But I need something like that.

I understand that this question was asked before, but in a different sense. I cannot use any obvious answers. I need something completely ready so that it is useful to me, which was not in the answers in another question.

+8
c ++ function types overloading
source share
9 answers

You should start with this:

 template<typename T> T RetrieveValue(std::string key) { //get value and convert into T and return it } 

To support this feature, you need to work a bit to convert the value to type T One simple way to convert a value might be the following:

 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 need to call this function as:

 int x = RetrieveValue<int>(key); 

You might not mention int twice if you could do this:

 Value RetrieveValue(std::string key) { //get value std::string value = get_value(key, etc); return { value }; } 

where Value implemented as:

 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 you want, right?

+20
source share

If you know that your value can never be something like zero or negative, just return the structure holding the int, and double and zero the one you don't need ...

This is a cheap and dirty but easy way ...

 struct MyStruct{ int myInt; double myDouble; }; MyStruct MyFunction(){ } 
+1
source share

Regardless of whether it is overload or specialization, you need information that should be in the signature of the function. You can pass the variable as an unused second 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); 
+1
source share

If datastrings are compile-time constants (as said in a reply to my comment), you can use template magic to do the job. An even simpler option is to not use strings at all, but some data types that allow you to overload the 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 
+1
source share

Unfortunately, there is no way to overload the return type of the function, see this answer Overload by return type

0
source share
 int a=itoa(retrieveValue(dataString)); double a=ftoa(retrieveValue(dataString)); 

both return a string.

0
source share

As an alternative to solving the template, you can return the function a link or a pointer to a class, and then subclass this class to contain the different types of data that you want to return. RetrieveValue will then return a reference to the appropriate subclass.

This would allow the user to pass the returned object to other functions without knowing which subclass it belongs to.

Then the problem in this case will become one of the ways of managing memory - choosing a function that allocates the returned object, and which function deletes it, and when in this way we avoid memory leaks.

0
source share

The only reasonable 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); 
0
source share

Since you used an example that was not what you wanted, you dropped all a little.

You really have a setting (calling a function with a return value of this function whose return type is unrecognizable) will not work, because function calls will be resolved at compile time.

Then you are limited to the runtime solution. I recommend the visitor template and you will have to significantly change your design to make this change. Actually there is no other way to do this that I see.

-2
source share

All Articles