[.net] How to make function that return more than 1 value in Visual C++?

Started by
11 comments, last by noe 16 years, 2 months ago
Hi I am using Visual C++. Is it possible to make a function that return more than one value? At least they have the same type. For example, I want to get the file name and the file content but both of them of the same type, which is String. I don't know if it is possible or not. If it is possible, how to do that? Please give me a code sample if possible, in C# also no problem. Thank you very much.
Advertisement
You could make a structure out of two strings, like this:
struct Data
{
std::string name;
std::string data;
};

then make your function like this:

Data doStuff()
{
Data stuff;
stuff.name = getName();
stuff.data = readData();
return stuff;
}

Or, you could make a function that accepts references to data somewhere else. Like this:

int main()
{
std::string name, data;
doStuff(&name, &data);
}

and then perform operations straight into name and data like that. There are several options. I would probably go with the structure though.
Typically speaking in C++ to return multiple values from a function/method you would pass by reference.

void doSomething(int& foo, int& bar);


If you really really really want to have a function/method return "multiple values" you need to wrap the values in something. That boils down to a struct/class like the above poster, or a container such as std::pair, for two values, or boost::tuple, for more values.
Boost ftw!!!

Seriously though, I'm all for templates to solve a problem:

template< typename _T0, typename _T1 >
class TPair
{
public:
_T0 type_0;
_T1 type_1;
};

template< typename _T0, typename _T1 >
TPair< _T0, _T1 > make_pair( _T0 arg_0, _T1 arg_1 )
{
TPair< _T0, _T1 > ret_val;
ret_val.type_0 = arg_0;
ret_val.type_1 = arg_1;
return (ret_val);
}

And to use ..

TPair< int, bool > my_func( int arg_0, bool arg_1 ... )
{
TPair< int, bool > ret_val = make_pair( arg_0, arg_1 );
return ret_val;
}
Quote:Original post by TheGilb
Boost ftw!!!

Seriously though, I'm all for templates to solve a problem:

template< typename _T0, typename _T1 >
class TPair
{
public:
_T0 type_0;
_T1 type_1;
};

template< typename _T0, typename _T1 >
TPair< _T0, _T1 > make_pair( _T0 arg_0, _T1 arg_1 )
{
TPair< _T0, _T1 > ret_val;
ret_val.type_0 = arg_0;
ret_val.type_1 = arg_1;
return (ret_val);
}

And to use ..

TPair< int, bool > my_func( int arg_0, bool arg_1 ... )
{
TPair< int, bool > ret_val = make_pair( arg_0, arg_1 );
return ret_val;
}


that is definitely the way to go, especially with C++0x coming soon (with tuples in standard), but instead of handmade pair, you could just use std::pair<std::string, std::string> for the return type
std::pair and std::make_pair already exist.
Quote:Original post by donny dont
Typically speaking in C++ to return multiple values from a function/method you would pass by reference.


That is the C way. C++ provides a templated pair type for returning pairs of values (these are used almost universally throughout the standard library), and you should be using a custom type for returning triples (or more) because they represent a semantic that needs naming.
Quote:Original post by ToohrVyk
Quote:Original post by donny dont
Typically speaking in C++ to return multiple values from a function/method you would pass by reference.


That is the C way. C++ provides a templated pair type for returning pairs of values (these are used almost universally throughout the standard library), and you should be using a custom type for returning triples (or more) because they represent a semantic that needs naming.


Stylistically I consider returning multiple values more the realm of a scripting language, such as Lua and Python.

foo, bar = fooBar()


Its more elegant in the scripting languages while with C++ its hacked in there.

std::pair fooBarPair;fooBarPair = fooBar();// fooBarPair.x = foo// fooBarPair.y = bar


What is x and y? not particularly descriptive.

Then add into the equation what pass by reference and pass by value mean. If the variable is small, such as an int, and any modifications within the function/method can be discarded then pass by value. If it will be modified pass by reference which goes the same for larger types, such as a std::vector. But if the large type won't be changed within the function/method pass by const reference.

Those are the rules I was brought up on with C++.
as always you have boost to the rescue with tuples :
http://www.boost.org/libs/tuple/doc/tuple_users_guide.html

for example :

int i; char c; double d;boost::tie(i, c, d) = boost::make_tuple(1,'a', 5.5);std::cout << i << " " <<  c << " " << d;Foo foo;Bar bar;boost::tie(foo, bar) = method_that_returns_fooBar();
perhaps this is a better example :

boost::tuple<int, double, char> do_stuff (){...return boost::make_tuple(1, 2.234, 'a');}int idouble d;char c;boost::tie(i, d, boost::tuples::ignore) = do_stuff();


(I love boost)

This topic is closed to new replies.

Advertisement