Conversion operator that must convert return...

Discussion in 'C++' started by Noah Roberts, Aug 30, 2011.

  1. Noah Roberts

    Noah Roberts Guest

    I am trying to do something like so:

    std::tie(x,y) = object;

    My initial attempt was something like so:

    struct attempt0
    {
    template < typename ... T >
    operator std::tuple<T...> ()
    {
    return std::tuple<T...>();
    }
    };

    The problem here is that tie returns a tuple of reference types, I
    can't just construct and return an empty one. It is assignable from
    tuples that have matching non-reference types though so my next naive
    attempt was:

    struct attempt1
    {
    template < typename ... T >
    operator std::tuple<typename std::remove_reference<T>::type...>()
    {
    return std::tuple<typename std::remove_reference<T>::type...>();
    }
    };

    This version is of course not recognized though. Third attempt was:

    struct attempt2
    {
    template < typename ... T >
    operator std::tuple<T...>()
    {
    return std::tuple<typename std::remove_reference<T>::type...>();
    }
    };

    I didn't expect this to work and it of course didn't.

    Sitting here trying to come up with legal C++ to do what I'm trying
    and I can't think of any. Any ideas?
    Noah Roberts, Aug 30, 2011
    #1
    1. Advertising

  2. On 8/30/2011 1:13 PM, Noah Roberts wrote:
    > I am trying to do something like so:
    >
    > std::tie(x,y) = object;
    >
    > My initial attempt was something like so:
    >
    > struct attempt0
    > {
    > template< typename ... T>
    > operator std::tuple<T...> ()
    > {
    > return std::tuple<T...>();
    > }
    > };
    >
    > The problem here is that tie returns a tuple of reference types, I
    > can't just construct and return an empty one. It is assignable from
    > tuples that have matching non-reference types though so my next naive
    > attempt was:
    >
    > struct attempt1
    > {
    > template< typename ... T>
    > operator std::tuple<typename std::remove_reference<T>::type...>()
    > {
    > return std::tuple<typename std::remove_reference<T>::type...>();
    > }
    > };
    >
    > This version is of course not recognized though. Third attempt was:
    >
    > struct attempt2
    > {
    > template< typename ... T>
    > operator std::tuple<T...>()
    > {
    > return std::tuple<typename std::remove_reference<T>::type...>();
    > }
    > };
    >
    > I didn't expect this to work and it of course didn't.
    >
    > Sitting here trying to come up with legal C++ to do what I'm trying
    > and I can't think of any. Any ideas?


    Not that I know much, but it seems that you're trying to guess what your
    object is going to be assigned to. That's impossible. Perhaps you
    should consider some other syntax altogether. What problem are you
    trying to solve?

    BTW, a usual solution when you need to return an "empty" reference is to
    have a static object [in your class] a reference to which you can return
    (and check against) in case you need "an empty one".

    V
    --
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Aug 30, 2011
    #2
    1. Advertising

  3. Noah Roberts

    Gil Guest

    On Aug 30, 1:13 pm, Noah Roberts <> wrote:
    > I am trying to do something like so:
    >
    > std::tie(x,y) = object;
    >
    > My initial attempt was something like so:
    >
    > struct attempt0
    > {
    >   template < typename ... T >
    >   operator std::tuple<T...> ()
    >   {
    >     return std::tuple<T...>();
    >   }
    >
    > };
    >
    > The problem here is that tie returns a tuple of reference types, I
    > can't just construct and return an empty one.  It is assignable from
    > tuples that have matching non-reference types though so my next naive
    > attempt was:
    >
    > struct attempt1
    > {
    >   template < typename ... T >
    >   operator std::tuple<typename std::remove_reference<T>::type...>()
    >   {
    >     return std::tuple<typename std::remove_reference<T>::type...>();
    >   }
    >
    > };
    >
    > This version is of course not recognized though.  Third attempt was:
    >
    > struct attempt2
    > {
    >   template < typename ... T >
    >   operator std::tuple<T...>()
    >   {
    >     return std::tuple<typename std::remove_reference<T>::type...>();
    >   }
    >
    > };
    >
    > I didn't expect this to work and it of course didn't.
    >
    > Sitting here trying to come up with legal C++ to do what I'm trying
    > and I can't think of any.  Any ideas?


    you have to *add* reference to match the tie decl type... see below.

    /**
    * @file: tie_test.cpp
    * @author: gil
    * Distributed under the Boost Software License, Version 1.0.
    */

    #include <tuple>
    #include <iostream>
    #include <functional>

    template< typename X, typename Y >
    struct object {
    object( X const & x, Y const & y ) : x( x ), y( y ) { }
    operator std::tuple< X&, Y& >() {
    return std::make_tuple( std::ref( x ), std::ref( y ) );
    }
    X x; Y y;
    };

    int main( ) {

    object< int, int > c0( 0, 1 );
    int i, d;
    std::tie( i, d ) = c0; /* problem solved */
    std::cout << i << " " << d << std::endl;

    }
    Gil, Aug 30, 2011
    #3
  4. Noah Roberts

    Noah Roberts Guest

    On Aug 30, 3:24 pm, Gil <> wrote:
    > On Aug 30, 1:13 pm, Noah Roberts <> wrote:
    > > I am trying to do something like so:

    >
    > > std::tie(x,y) = object;

    >
    > > My initial attempt was something like so:

    >
    > > struct attempt0
    > > {
    > >   template < typename ... T >
    > >   operator std::tuple<T...> ()
    > >   {
    > >     return std::tuple<T...>();
    > >   }

    >
    > > };

    >
    > > The problem here is that tie returns a tuple of reference types, I
    > > can't just construct and return an empty one.  It is assignable from
    > > tuples that have matching non-reference types though so my next naive
    > > attempt was:

    >
    > > struct attempt1
    > > {
    > >   template < typename ... T >
    > >   operator std::tuple<typename std::remove_reference<T>::type...>()
    > >   {
    > >     return std::tuple<typename std::remove_reference<T>::type...>();
    > >   }

    >
    > > };

    >
    > > This version is of course not recognized though.  Third attempt was:

    >
    > > struct attempt2
    > > {
    > >   template < typename ... T >
    > >   operator std::tuple<T...>()
    > >   {
    > >     return std::tuple<typename std::remove_reference<T>::type...>();
    > >   }

    >
    > > };

    >
    > > I didn't expect this to work and it of course didn't.

    >
    > > Sitting here trying to come up with legal C++ to do what I'm trying
    > > and I can't think of any.  Any ideas?

    >
    > you have to *add* reference to match the tie decl type... see below.
    >
    > /**
    >  * @file:   tie_test.cpp
    >  * @author: gil
    >  * Distributed under the Boost Software License, Version 1.0.
    >  */
    >
    > #include <tuple>
    > #include <iostream>
    > #include <functional>
    >
    > template< typename X, typename Y >
    > struct object {
    >   object( X const & x, Y const & y ) : x( x ), y( y ) { }
    >   operator std::tuple< X&, Y& >() {
    >     return std::make_tuple( std::ref( x ), std::ref( y ) );


    What if x & y are calculated?

    >   }
    >   X x; Y y;
    >
    > };
    >
    > int main( ) {
    >
    >   object< int, int > c0( 0, 1 );
    >   int i, d;
    >   std::tie( i, d ) = c0; /* problem solved */
    >   std::cout << i << " " << d << std::endl;
    > }
    Noah Roberts, Aug 30, 2011
    #4
  5. Noah Roberts

    SG Guest

    On 30 Aug., 19:13, Noah Roberts wrote:
    >
    > I am trying to do something like so:
    >
    > std::tie(x,y) = object;
    >
    > [object is not a tuple but of another custom type I'm writing]
    >
    > Sitting here trying to come up with legal C++ to do what I'm trying
    > and I can't think of any.  Any ideas?


    Why are the conversion operators in all your attempts templates? Why
    do you try to default-construct the resulting tuples? What is it, that
    you are actually trying to do here?

    There are only two non-template assignment operators of tuple<>. And
    these are the only ones that the compiler will consider. So, you
    provide a conversion to that specific tuple type, or you don't do it
    at all. operator= has to be a non-static member. So, you also can't
    provide your own one as a free function.

    Alternatives:
    (1) assign(tie(x,y),object);
    (2) tie(x,y) = object.as_tuple();

    Whether 2 works for you, I don't know. As I said, I don't understand
    why you would want your conversion operator to be a template.

    SG
    SG, Aug 31, 2011
    #5
    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. Arvid Requate
    Replies:
    2
    Views:
    983
    Alf P. Steinbach
    Jun 23, 2006
  2. hurcan solter
    Replies:
    3
    Views:
    727
    Cholo Lennon
    Aug 29, 2007
  3. hemantdesai
    Replies:
    0
    Views:
    325
    hemantdesai
    Jan 28, 2008
  4. , India
    Replies:
    2
    Views:
    457
    Fraser Ross
    Sep 15, 2009
  5. cronusf
    Replies:
    12
    Views:
    487
Loading...

Share This Page