CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    Jul 2009
    Posts
    13

    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!

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Different return type depending on data

    Quote Originally Posted by metzenes View Post
    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.
    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
    Last edited by Paul McKenzie; July 2nd, 2009 at 04:19 AM.

  3. #3
    Join Date
    Feb 2009
    Location
    India
    Posts
    444

    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
    «_Superman
    I love work. It gives me something to do between weekends.

    Microsoft MVP (Visual C++)

  4. #4
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    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.

  5. #5
    Join Date
    Nov 2006
    Posts
    1,611

    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?
    If my post was interesting or helpful, perhaps you would consider clicking the 'rate this post' to let me know (middle icon of the group in the upper right of the post).

  6. #6
    Join Date
    Jul 2009
    Posts
    13

    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?

  7. #7
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: Different return type depending on data

    Quote Originally Posted by metzenes View Post
    I think VARIANT it's a good option for solving that.
    I think it would be better to go with Lindley's suggestion.
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

  8. #8
    Join Date
    Nov 2006
    Posts
    1,611

    I second that..

    A base column container, or a container of a base type, or a template derivative from a base type - all applicable.

    The point here is that your puzzle should be turned inside out.

    Instead of concentrating on obtaining a return type out of the column data, aimed at suiting the caller's need for a particular type, turn the puzzle inside out and call a generic operation which performs a callback based on the derived type.

    Consider each of the reasons for the call, for which the ultimate type is required. It could be a calculation, it could be for display, it could be to obtain the data for another use. Whatever they are, form a collection of these based on the generic notion of the column. Let the virtual derivative deal with the actual method, which in turn calls an overload to respond appropriately based on type.

    For example, say the purpose is calculation. Create a small collector, something like:


    Code:
    class sum_collector
    {
     private:
     float sum;
    
     public:
    
     sum_collector() : sum( 0.0f ) {}
    
     accumulate( float &f ) { sum += f; }
    
    };

    create a sum_collector and pass it to a generic function which takes (or operates on) a column, without respect to type.

    The virtual function which a "float" version responds with would call accumulate with it's float member, but if it's a string it would ignore the call.

    The visitor pattern deals with this issue in a double dispatch scenario. Say, for example, your columns also included int and double types. In order to perform some operations with a combination of int, double and/or float, you'd need the visitor pattern, or some form of double dispatch to solve the issue.

    There are various ways to consider and solve the puzzle, and virtual functions are generally at the heart of it. It is genuinely a mistake to insist the puzzle be solved from the caller's perspective. The caller should not have to know the type, it should be able to consider the call on whatever type - let the virtual derivative figure that out, and let it make a callback to complete the appropriate type-oriented behavior.
    If my post was interesting or helpful, perhaps you would consider clicking the 'rate this post' to let me know (middle icon of the group in the upper right of the post).

  9. #9
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Different return type depending on data

    Quote Originally Posted by metzenes View Post
    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.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured