Sign in to follow this  
chrisliando

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

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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;
}

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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++.

Share this post


Link to post
Share on other sites
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();



Share this post


Link to post
Share on other sites
perhaps this is a better example :


boost::tuple<int, double, char> do_stuff ()
{
...
return boost::make_tuple(1, 2.234, 'a');
}

int i
double d;
char c;
boost::tie(i, d, boost::tuples::ignore) = do_stuff();



(I love boost)

Share this post


Link to post
Share on other sites
Quote:
Original post by chrisliando
Do you have code sample in Managed C++? because I don't understand how to implement using all the codes you guys gave me..

I'll be waiting..

Thank you very much..

I'm not really familiar with Managed C++. I really only know its some Microsoft extensions to C++ to make it "safer" and work better with .NET.

Boost is meant to be a set of cross-platform libraries for C++. That means it won't use any Microsoft extensions as this would break from the C++ standard. Anything else I would assume would be the same minus the "safe methods" Visual Studio recommends.

Share this post


Link to post
Share on other sites
Quote:
Original post by chrisliando
Do you have code sample in Managed C++? because I don't understand how to implement using all the codes you guys gave me..

I'll be waiting..

Thank you very much..


If returning tuples/pairs approach is too difficult for you, then stick with pass by pointer or reference (use pointer for optional return values, and references for mandatory ones). There is nothing in managed C++ (or C# for that matter) that can help with that either. Anyway I encourage you to at least try std::pair, because tuples and tie() are to become standard soon

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this