Conversion operator that must convert return...

N

Noah Roberts

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?
 
V

Victor Bazarov

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
 
G

Gil

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;

}
 
N

Noah Roberts

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?
 
S

SG

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
 

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

Forum statistics

Threads
473,744
Messages
2,569,479
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top