.. a way to return two references from a function ?

L

Lutz Altmann

hello,

i try to write a class-function which can return two arguments by
reference.
My idea was to encapsulate the references in a struct :

struct DataUnit
{
SomeClassType& m_object1;
SomeOtherClassType& m_object2;
};

So that the function can return the two references by using the
struct :

DataUnit processSomething();

My question is: How can i create the struct in the function ?
I've tried the following:

DataUnit returnValue = { m_someobject1,m_someobject2};

but it doesnt work.

Is there a way to initialize the references ? maybe there is another/
better
way to return two references from the function?

Note: The function-caller only has access to the interface of the
classes (of the return references)!

Thanks in advance,
Lutz
 
D

dave_mikesell

hello,

i try to write a class-function which can return two arguments by
reference.

Instead of trying to return multiple args, you can pass references to
the function:

void myFunction(SomeObj & so, AnotherObj & ao) { ... }
 
F

fred.l.kleinschmidt

hello,

i try to write a class-function which can return two arguments by
reference.
My idea was to encapsulate the references in a struct :

struct DataUnit
{
  SomeClassType& m_object1;
  SomeOtherClassType& m_object2;

};

So that the function can return the two references by using the
struct :

DataUnit processSomething();

My question is: How can i create the struct in the function ?
I've tried the following:

DataUnit returnValue = { m_someobject1,m_someobject2};

but it doesnt work.

Is there a way to initialize the references ? maybe there is another/
better
way to return two references from the function?

Note: The function-caller only has access to the interface of the
classes (of the return references)!

Thanks in advance,
Lutz

Return a pointer to the struct, not the struct.

DataUnit *processingSomething() {
DataUnit *x = new DataUnit();
// ...
return x;
}

But why bother with the struct in the first place?

void procewsingSomething( SomeClassType &a, SomeOtherClassType &b) {
...
}
 
L

Lutz Altmann

Return a pointer to the struct, not the struct.

DataUnit *processingSomething() {
DataUnit *x = new DataUnit();
// ...
return x;

}

But why bother with the struct in the first place?

void procewsingSomething( SomeClassType &a, SomeOtherClassType &b) {
...

}

Hi,

The Problem with your solution is, that the caller needs to have the
implemenation of SomeClassType and SomeOtherClassType (He has to
create the objects before he can call the function).
In my environment the caller only knows the abstract interface of the
classes.
 
D

dave_mikesell

The Problem with your solution is, that the caller needs to have the
implemenation of SomeClassType and SomeOtherClassType (He has to
create the objects before he can call the function).
In my environment the caller only knows the abstract interface of the
classes.

Use pointers and create the concrete objects in the function. The
caller still only needs to know about the abstract base. You can use
something like boost::shared_ptr if you don't want to worry about who
deletes the pointers when they're no longer needed.
 
T

tragomaskhalos

hello,

i try to write a class-function which can return two arguments by
reference.
My idea was to encapsulate the references in a struct :

struct DataUnit
{
  SomeClassType& m_object1;
  SomeOtherClassType& m_object2;

};

So that the function can return the two references by using the
struct :

DataUnit processSomething();

My question is: How can i create the struct in the function ?
I've tried the following:

DataUnit returnValue = { m_someobject1,m_someobject2};

but it doesnt work.

Is there a way to initialize the references ? maybe there is another/
better
way to return two references from the function?

Note: The function-caller only has access to the interface of the
classes (of the return references)!

Thanks in advance,
Lutz

Why don't you just add a constructor?

struct DataUnit
{
SomeClassType& m_object1;
SomeOtherClassType& m_object2;

DataUnit(SomeClassType& object1,
SomeOtherClassType& object2) :
m_object1(object1), m_object2(object2)
{}
};

Then assuming eg ...
SomeClassType glob1;
SomeOtherClassType glob2;

You can do ....
DataUnit processSomething()
{
return DataUnit(glob1, glob2);
}

I assume from your use of references that you don't want
to return SomeClassType/SomeOtherClassType objects created
locally within processSomething(), as they will be out of
scope by the time processSomething returns:
DataUnit processSomething()
{
SomeClassType auto1;
SomeOtherClassType auto2;
// THIS WILL NOT WORK
return DataUnit(auto1, auto2);
}
 
L

Lutz Altmann

Why don't you just add a constructor?

struct DataUnit
{
SomeClassType& m_object1;
SomeOtherClassType& m_object2;

DataUnit(SomeClassType& object1,
SomeOtherClassType& object2) :
m_object1(object1), m_object2(object2)
{}

};

Then assuming eg ...
SomeClassType glob1;
SomeOtherClassType glob2;

You can do ....
DataUnit processSomething()
{
return DataUnit(glob1, glob2);

}

I assume from your use of references that you don't want
to return SomeClassType/SomeOtherClassType objects created
locally within processSomething(), as they will be out of
scope by the time processSomething returns:
DataUnit processSomething()
{
SomeClassType auto1;
SomeOtherClassType auto2;
// THIS WILL NOT WORK
return DataUnit(auto1, auto2);

}

Thanks for your answer,

No i don't want to return local variables (i want to return object-
variables).
I think i'll use your constructor-solution to avoid a pointer version.
 
E

Eric.Malenfant

Lutz said:
hello,

i try to write a class-function which can return two arguments by
reference.
My idea was to encapsulate the references in a struct :

struct DataUnit
{
SomeClassType& m_object1;
SomeOtherClassType& m_object2;
};
[snip]

Boost.Tuple seems to fit nicely here :
http://www.boost.org/libs/tuple/doc/tuple_users_guide.html#constructing_tuples
Look at the make_tuple section and, in particular, to the use of ref()
and cref().

Non-tested example:
class SomeClass
{
public:
boost::tuple<SomeClassType&, SomeOtherClassType&> Foo()
{
return boost::make_tuple(boost::ref(m_SomeClass),
boost::ref(m_SomeOtherClass));
}
private:
SomeClassType m_SomeClass;
SomeOtherClassType m_SomeOtherClass;
};

HTH,

Éric Malenfant
 
M

Matthias Buelow

Puppet_Sock said:
Don't. Re-factor your problem so that does not happen.
Socks

I disagree, returning a small number of values (2, 3) in a struct is in
many cases an elegant solution and doesn't necessarily incur a
performance hit.

Quite a few times I have wished for C or C++ to have multiple return
values; if you've worked with them, you tend to miss them in languages
that don't have them.
 
J

Joe Greer

I disagree, returning a small number of values (2, 3) in a struct is in
many cases an elegant solution and doesn't necessarily incur a
performance hit.

Quite a few times I have wished for C or C++ to have multiple return
values; if you've worked with them, you tend to miss them in languages
that don't have them.

The OP might want to look at tr1::tuple() and tr1::tie(), They provide the
ability to return and assign multiple values at once. If tr1 isn't
available, then look at the boost libraries. They have implementations of
these.

joe
 
T

Tomás Ó hÉilidhe

I've tried the following:

DataUnit returnValue = { m_someobject1,m_someobject2};

but it doesnt work.


The following compiles just fine for me:

struct TwoIntRefs {
int &i, &j;
};

TwoIntRefs Func()
{
static int a = 55, b = 44;

TwoIntRefs const tir = {a,b};

return tir;
}

int main()
{
TwoIntRefs const tir = Func();

tir.i = 77;

tir.j = 33;
}
 
J

jason.cipriani

(e-mail address removed)...
The following compiles just fine for me:

struct TwoIntRefs {
int &i, &j;
};

There is also std::pair<int&,int&>, although then you have to refer to
things as "first" and "second".
 
A

Andrey Tarasevich

Lutz said:
i try to write a class-function which can return two arguments by
reference.
My idea was to encapsulate the references in a struct :

struct DataUnit
{
SomeClassType& m_object1;
SomeOtherClassType& m_object2;
};

So that the function can return the two references by using the
struct :

DataUnit processSomething();

My question is: How can i create the struct in the function ?
I've tried the following:

DataUnit returnValue = { m_someobject1,m_someobject2};

but it doesnt work.
...

What exactly "doesn't work"?
 
L

Lutz Altmann

Lutz said:
i try to write a class-function which can return two arguments by
reference.
My idea was to encapsulate the references in a struct :
struct DataUnit
{
SomeClassType& m_object1;
SomeOtherClassType& m_object2;
};

[snip]

Boost.Tuple seems to fit nicely here :http://www.boost.org/libs/tuple/doc/tuple_users_guide.html#constructi...
Look at the make_tuple section and, in particular, to the use of ref()
and cref().

Non-tested example:
class SomeClass
{
public:
boost::tuple<SomeClassType&, SomeOtherClassType&> Foo()
{
return boost::make_tuple(boost::ref(m_SomeClass),
boost::ref(m_SomeOtherClass));
}
private:
SomeClassType m_SomeClass;
SomeOtherClassType m_SomeOtherClass;
};

HTH,

Éric Malenfant

nice,

for me it seems to be a very elegant solution.
i think i'll use this one or the template provided by the stl
std::pair<int&,int&>

thanks a lot
 
L

Lutz Altmann

What exactly "doesn't work"?

sorry it was my fault - what i described at the beginning was not
really wrong ..
there was actually no problem with the code - blame on me
 
R

Richard Herring

Matthias Buelow said:
I disagree, returning a small number of values (2, 3) in a struct is in
many cases an elegant solution and doesn't necessarily incur a
performance hit.

I think the objection is to returning references, not tuples.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,007
Latest member
obedient dusk

Latest Threads

Top