www.digitalmars.com         C & C++   DMDScript  

c++.beta - boost tuples

reply Richard Grant <fractal clark.net> writes:
Christof,

Have you used boost::tuples with the recent beta, and if so are there any
problems of note?

I have had some good success using them, but I'm chasing a generic compiler
error, and I wonder if perhaps something is wrong in the tuple precompiler maze.

Richard
Feb 09 2003
parent reply Richard Grant <fractal clark.net> writes:
Tuples uses recursive template member function template, and the inline keyword
seems to be causing some troubles.. The following compiles and executes if the
inline keyword is removed.

#include <iostream>

template <int N>
struct A {
template <class T1>
inline static T1 get(T1& t) {
// Error:  storage class is illegal in this context
std::cout << "Recurse: " << N << std::endl;
return A<N-1>:: get<T1>(t);
// Error: no instance of class 'A<0>' for member 'A<0>::get'
}
};

template<>
struct A<0> {
template <class T1>
inline static T1 get(T1& t) {
// Error:  storage class is illegal in this context
std::cout << "Recurse: Final" << std::endl;
return t;
}
};

struct B { };

void main() {
B b;
A<3>::get<B>(b);
// Error: no instance of class 'A<3>' for member 'A<3>::get'
}

Richard
Feb 10 2003
parent reply "Walter" <walter digitalmars.com> writes:
Got it!
Feb 10 2003
parent reply Richard Grant <fractal clark.net> writes:
In the example below, the output matches the correct base class representation.
However, the conversion from derived class to base class fails. You can change
the last line like get_class<1> for another set of errors like:

Warning 11: non-const reference initialized to temporary
Error: need explicit cast for function parameter 1 to get
from: cons<int ,null_type >
to  : cons<int ,null_type >

Sorry the example is long, but getting the inheritence list from the
implementation was a pain. There is probably something else lurking, but I'm
hoping that this is a good start. 

Richard

struct null_type {};

inline const null_type cnull() { return null_type(); }

template <class T0 = null_type, class T1 = null_type,
class T2 = null_type> class tuple;

template <class HT, class TT>
struct cons {

typedef HT head_type;
typedef TT tail_type;

head_type head;
tail_type tail;

template <class T1, class T2, class T3>
cons( T1& t1, T2& t2, T3& t3 )
: head (t1),
tail (t2, t3, cnull())
{ }

template <class T2, class T3>
cons( const null_type& t1, T2& t2, T3& t3 )
: head (),
tail (t2, t3, cnull())
{}

};

template <class HT>
struct cons<HT, null_type> {

typedef HT head_type;
typedef null_type tail_type;
typedef cons<HT, null_type> self_type;

head_type head;

template<class T1>
cons(T1& t1, const null_type&, const null_type&)
: head (t1) {}

cons(const null_type&, const null_type&, const null_type&)
: head () {}
};

template <class T0, class T1, class T2>
struct mapper
{
typedef cons<T0,
typename mapper<T1, T2, null_type>::type
 type;

template <> struct mapper<null_type, null_type, null_type> { typedef null_type type; }; template <class T0, class T1, class T2> class tuple : public mapper<T0, T1, T2>::type { public: typedef typename mapper<T0, T1, T2>::type inherited; typedef typename inherited::head_type head_type; typedef typename inherited::tail_type tail_type; tuple() : inherited(cnull(), cnull(), cnull()) {} tuple(const T0& t0) : inherited(t0, cnull(), cnull()) {} tuple(const T0& t0, const T1& t1) : inherited(t0, t1, cnull()) {} tuple(const T0& t0, const T1& t1, const T2& t2) : inherited(t0, t1, t3) {} }; template <> class tuple<null_type, null_type, null_type> : public null_type { public: typedef null_type inherited; }; template< int N > struct get_class { template<class RET, class HT, class TT > static RET get(cons<HT, TT>& t) { return get_class<N-1>:: get<RET>(t.tail); } }; template<> struct get_class<0> { template<class RET, class HT, class TT> static RET get(cons<HT, TT>& t) { return t.head; } }; void main() { tuple<int,int> test(10, 12); int a = get_class<0>::get<int>(test); // Warning 11: non-const reference initialized to temporary // Error: need explicit cast for function parameter 1 to get // from: tuple<int ,int ,null_type > // to : cons<int ,cons<int ,null_type > > }
Feb 10 2003
parent reply Richard Grant <fractal clark.net> writes:
In article <b29e98$1b8$1 digitaldaemon.com>, Richard Grant says...
In the example below, the output matches the correct base class

ok, that entire example was wrong. After spending some time with it and the tuple sources, I have found that the problem is in the public interface and not the representation. The good news is that I can report that the entire underlying representation works with current beta. The bad news is that according to standard (see 14.8.1 for an example - not a justification), explicit argument specification and argument deduction are in need of adjustment. Here's the test case: template <class T1> struct A { }; template<int N, class HT> int get(A<HT>& c) { int i = N; return i; } int main() { A<int> a; int j = get<1>(a); // Error: illegal operand types // Had: int // and: A<int > } Richard
Feb 21 2003
parent "Walter" <walter digitalmars.com> writes:
Great!
Feb 21 2003