Different return type depending on data
I'm designing a class where there's a method that should return a different data type depending on certain circunstances.
Specifically, I'm reading from a text file. If the data found are strings of characters, I'd like to return a vector of strings. On the other hand, I'd like to return a vector of floats if the data are numbers.
template <typename T>
vector<T> funcion(string typeConversion){
if (typeConversion== 'String')
//...
return list<string>
else if (typeConversion == 'Number')
//...
return vector<float>
}
I don't think this is possible with C++ (in Python, for instance, I think that methods can return every data type).
Do you know any alternative to solve my problem?
Thanks!
Re: Different return type depending on data
Quote:
Originally Posted by
metzenes
Specifically, I'm reading from a text file. If the data found are strings of characters, I'd like to return a vector of strings. On the other hand, I'd like to return a vector of floats if the data are numbers.
OK.
Quote:
I don't think this is possible with C++
Instead of thinking of other languages, you should concentrate on how to solve this using C++.
You are given a string, and you are doing something different when a different string is given to you. That is basically what this all boils down to. The problem is that your mindset is on "returning" something, when it could be solved by redesigning your code so that it doesn't need to return anything specific. Maybe that entire testing of the string shouldn't be in the template to begin with.
Second, your example is faulty -- you are returning a list<T>, when the return type is vector<T>.
But in general it is possible in C++ using something called "compile-time polymorphism" or policy-based programming. What you are looking for is something called "template specialization". Do a search on CodeGuru, and you will see samples of this.
Regards,
Paul McKenzie
Re: Different return type depending on data
You should be able to do this by returning a union of different datatypes similar to the VARIANT structure. See here - VARIANT and VARIANTARG
Re: Different return type depending on data
One solution (which I'm using a variation on myself at the moment) is to define a common base class Base such that Derived<string> and Derived<float> both inherit from it. Then you can specify the return type as a Base*, but actually return a pointer to whichever type you actually have.
Of course, as with all things polymorphic, you have dynamic memory forced on you a bit more than you'd probably like.
Re: Different return type depending on data
There are two basic problems.
First, you can't overload a function, even by templates like this, based only on the return type.
Second, by the time you can supply a string, you already MUST know the return type, obviating the necessity of the string specifying the return type.
What you can do is overload using a reference...
template <typename T> funcion( T & i ) {... }
Consider the calling code. If you're going to instantiate the function on behalf of a float, your call, if it were even possible, would have to be something like:
float v = convert<float>( floatstring );
Why would you want to provide a string stating the return type? It's redundant information. You could not determine the type of the return value based on the template - that is v isn't going to modulate it's type in this context, or any context in which you make a call (though the variant type is theoretically 'any' type, it is, itself, a type).
Since you can't overload based on return type, you would:
float v;
convert( v );
However, the context of this call is what's important. Is your reason for wanting a string based on some user input selection?
I'd need more to go on before I drift off into a tangent outside you're interest. What we need to know in order to be of help is why you're doing this and what the context is, how are you deciding what type to convert to?
Re: Different return type depending on data
Thank you all for all your interesting and helping answers!
I'll explain more in detail what I'm trying to do:
I'm reading a text file that includes loads of data ordered by columns. Each column contains a different kind of data (it can be text or numbers). My method should return a vector (or any other data structure) containing the data from the column provided.
Depending on what kind of data the column has, I'd return a vector<string> or vector<float>, for instance.
vector<T> method(string column_name){
ReadColumnFromFile()
if Column is text
return vector<string>
else if Colum is numbers
return vector<float>
}
I think VARIANT it's a good option for solving that.
Another problem is to know when the information should be a string or a number (float, for example). When I read from the file I always get a string. I thought about using atof() to convert the string to a float; if it works it'll be a number, if not it'll be a string. What do you think?
Re: Different return type depending on data
Quote:
Originally Posted by
metzenes
I think VARIANT it's a good option for solving that.
I think it would be better to go with Lindley's suggestion.
Re: Different return type depending on data
Quote:
Originally Posted by
metzenes
I'll explain more in detail what I'm trying to do:
I'm reading a text file that includes loads of data ordered by columns. Each column contains a different kind of data (it can be text or numbers). My method should return a vector (or any other data structure) containing the data from the column provided.
SQL libraries have already solved this problem in one sense: They require the calling code to know what type of data each column is expected to contain. So for instance, you could write getFloatColumn("MyColumnName") or getStringColumn("MyColumnName2"). The idea being that if you encounter some type of data other than what you're expecting, you just throw an exception.