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

Discussion in 'C++' started by Lutz Altmann, Feb 27, 2008.

  1. Lutz Altmann

    Lutz Altmann Guest

    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
     
    Lutz Altmann, Feb 27, 2008
    #1
    1. Advertising

  2. Lutz Altmann

    Guest

    On Feb 27, 8:54 am, Lutz Altmann <> wrote:
    > 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) { ... }
     
    , Feb 27, 2008
    #2
    1. Advertising

  3. Lutz Altmann

    Guest

    On Feb 27, 6:54 am, Lutz Altmann <> wrote:
    > 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) {
    ...
    }

    --
    Fred Kleinschmidt
     
    , Feb 27, 2008
    #3
  4. Lutz Altmann

    Grizlyk Guest

    Grizlyk, Feb 27, 2008
    #4
  5. Lutz Altmann

    Lutz Altmann Guest

    On 27 Feb., 16:37, wrote:
    > On Feb 27, 6:54 am, Lutz Altmann <> wrote:
    >
    >
    >
    > > 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) {
    > ...
    >
    > }
    >
    > --
    > Fred Kleinschmidt


    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.
     
    Lutz Altmann, Feb 27, 2008
    #5
  6. Lutz Altmann

    Guest

    On Feb 27, 9:50 am, Lutz Altmann <> wrote:

    >
    > 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.
     
    , Feb 27, 2008
    #6
  7. On Feb 27, 2:54 pm, Lutz Altmann <> wrote:
    > 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);
    }
     
    tragomaskhalos, Feb 27, 2008
    #7
  8. Lutz Altmann

    Lutz Altmann Guest

    On 27 Feb., 17:09, tragomaskhalos <>
    wrote:
    > On Feb 27, 2:54 pm, Lutz Altmann <> wrote:
    >
    >
    >
    > > 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);
    >
    > }


    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.
     
    Lutz Altmann, Feb 27, 2008
    #8
  9. Lutz Altmann

    Guest

    Lutz Altmann wrote:
    > 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
     
    , Feb 27, 2008
    #9
  10. Lutz Altmann

    Puppet_Sock Guest

    On Feb 27, 9:54 am, Lutz Altmann <> wrote:
    [snip]
    > i try to write a class-function which can return two arguments by
    > reference.


    Don't. Re-factor your problem so that does not happen.
    Socks
     
    Puppet_Sock, Feb 27, 2008
    #10
  11. Puppet_Sock wrote:

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

    > 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.
     
    Matthias Buelow, Feb 27, 2008
    #11
  12. Lutz Altmann

    Joe Greer Guest

    Matthias Buelow <> wrote in news:62lo6lF23mqf3U1
    @mid.dfncis.de:

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

    >> 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.
    >


    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
     
    Joe Greer, Feb 27, 2008
    #12

  13. > 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;
    }
     
    Tomás Ó hÉilidhe, Feb 27, 2008
    #13
  14. Lutz Altmann

    Guest

    "Tomás Ó hÉilidhe" <> wrote in message
    news:a73d7968-1705-4573-a23d-
    ...
    > 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".
     
    , Feb 27, 2008
    #14
  15. Lutz Altmann wrote:
    >
    > 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"?

    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Feb 27, 2008
    #15
  16. Lutz Altmann

    Lutz Altmann Guest

    On 27 Feb., 18:17, ""
    <> wrote:
    > Lutz Altmann wrote:
    > > 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#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
     
    Lutz Altmann, Feb 28, 2008
    #16
  17. Lutz Altmann

    Lutz Altmann Guest

    On 27 Feb., 22:14, Andrey Tarasevich <>
    wrote:
    > Lutz Altmann wrote:
    >
    > > 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"?
    >
    > --
    > Best regards,
    > Andrey Tarasevich


    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
     
    Lutz Altmann, Feb 28, 2008
    #17
  18. In message <>, Matthias Buelow
    <> writes
    >Puppet_Sock wrote:
    >
    >>> i try to write a class-function which can return two arguments by
    >>> reference.

    >> 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.


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

    >
    >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.


    --
    Richard Herring
     
    Richard Herring, Feb 28, 2008
    #18
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Roger Leigh
    Replies:
    8
    Views:
    457
    Karl Heinz Buchegger
    Nov 17, 2003
  2. Replies:
    3
    Views:
    470
    Victor Bazarov
    Nov 10, 2004
  3. DanielEKFA
    Replies:
    8
    Views:
    626
    DanielEKFA
    May 16, 2005
  4. Greenhorn
    Replies:
    15
    Views:
    847
    Keith Thompson
    Mar 6, 2005
  5. Eric Hofreiter
    Replies:
    4
    Views:
    142
    Eric Mahurin
    Nov 12, 2005
Loading...

Share This Page