How to return different types ?

Pages: 12
May 12, 2011 at 8:27pm
What makes it "the best" type? Do you mean the smallest memory foot print? The most flexible datatype? The coolest name? Depending on what you mean by "best" there are different approaches to this problem.

So far for your scenario I would write the function processing the variable as the template. But how are you getting your data?
May 13, 2011 at 12:17am
To elaborate, Computergeek01 suggests that your string-to-number function be templated so that when you decide to get, say, a float from the string it can do it.

Keep in mind that the STL already provides a stringstream that can do this. Likewise, you can use some of the <cstdlib> functions, like strtod().

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdexcept>
#include <sstream>

struct string_to_number_error: std::domain_error
  {
  explicit string_to_number_error( const std::string& what ):
    std::domain_error( what )
    { }
  };

template <typename N>
N string_to_number( const std::string& s )
  {
  N result;
  std::istringstream ss( s.substr( 0, s.find_last_not_of( " \f\n\r\t\v" ) + 1 ) );
  ss >> result;
  if (!ss.eof())
    throw string_to_number_error( std::string( "string_to_number: \"" ) + s + "\"" );
  return result;
  }
I just typed this in off the top of my head -- errors may be present...

What you may really want is to identify whether or not a string has, say, a fractional part, etc?
May 13, 2011 at 7:00am
I see that the solution is to have some 'VARIANT' data.
What can be a best solution ?
For example :

1
2
3
4
Class Variant
  Float set_Variant(Float my value) // constructors
  Int  set_Variant(int my value)
  Long set_Variant(Long my value)


I can have :
'type' Get_variant (return the type I set)

But I only can return a known type....

How to return the correct value without using switch neither if's
Thanks
May 13, 2011 at 9:30am
May 13, 2011 at 9:40am
Thanks. Maybe ...
May 13, 2011 at 9:43am
Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
union NumberUnion {
  int z;
  float x;
  double r;
};

enum NumberType { INT, FLOAT, DOUBLE };

struct Number {
  NumberUnion val;
  NumberType type;
};


Number string_to_number(string str) {
  Number num;
  if( /*str is best as an int*/ ) {
    num.type = INT;
    num.val.z = ...
  } else if( /*str is best as a float*/ ) {
    num.type = FLOAT;
    num.val.x = ...
  } else if( /*str is best as double*/ ) {
    num.type = DOUBLE;
    num.val.r = ...
  }
  return num;
}

int main() {
  string s = ...
  Number n = string_to_number(s);

  switch( n.type) {
   case INT:
    cout << "int " << n.val.z;
    break;
   case FLOAT:
    cout << "float " << n.val.x;
    break;
   case DOUBLE:
    cout << "double " << n.val.r;
    break;
  }

  cout << endl;
  return 0;
}
May 13, 2011 at 10:19am
yes I already have thought this
Thanks
May 13, 2011 at 12:00pm
I mean think about what you are asking. C++ must know what data type you are returning so it (at least) knows how much memory to allocate for it (along with other things like how to store it.) It doesn't make sense to allow a function to return a variety of data types in a language with such low-level control.
May 13, 2011 at 1:24pm
why dont u use Void Pointers for this.....
May 13, 2011 at 9:35pm
Well, I figure its worth one more shot...

Your design is flawed, and it is not the way C++ is designed to be used. When you invoke the function, you must have a specific type in mind -- there is no way around that (at least, that doesn't involve some significant grief and non-magic, hand-written stuff).

For the variant stuff, you may want to take a look at the Boost Any class
http://www.boost.org/doc/libs/1_46_1/doc/html/any.html
where they've done all the hard, tedious stuff for you...

but it still won't solve your problem. You cannot use a value unless you have a type for it!
Topic archived. No new replies allowed.
Pages: 12