E
er
Here's a toy linked list of references. I'd like to know if it's
conforming with C++ rules or not.
#include <iostream>
template<typename T> struct head_holder
{
explicit head_holder(T& t) : head_( &t ){}
T& head() const{ return (*this->head_); }
private:
T* head_;
};
template<typename T> struct tail_holder
{
tail_holder(T const& t) : tail_( t ){}
typedef T const& result_type;
T const& tail()const{ return this->tail_; }
private:
T const& tail_;
};
template<typename T> struct list1;
template<typename T> struct list0 : head_holder<T>
{
list0(T& x) : head_holder<T>( x ){}
list1<T> operator()(T& y)const{
return list1<T>(*this, y);
}
};
template<typename T> struct list2; template<typename T> struct list1 :
head_holder<T>
{
typedef list0<T> list0_; typedef tail_holder<list0_ >
tail_holder_;
list1(const list0_& t, T& y) : head_holder<T>( y ),
tail_holder( t ){}
list2<T> operator()(T& z)const{ return list2<T>(*this, z); }
typename tail_holder_::result_type tail()const{
return this->tail_holder.tail();
}
private:
tail_holder_ tail_holder;
};
template<typename T> struct list2 : head_holder<T>
{
typedef list1<T> list1_; typedef tail_holder<list1_ >
tail_holder_;
list2(const list1_& t, T& y) : head_holder<T>( y ),
tail_holder( t ){}
list2<T> operator()(T& z)const{ return list2<T>(*this, z); }
typename tail_holder_::result_type tail()const{
return this->tail_holder.tail();
}
private:
tail_holder_ tail_holder;
};
template<typename T> list0<T> make( T& x ){ return list0<T>( x ); }
template<typename T>list0<T const> make( T const& x ){ return list0<T
const>( x ); }
int main()
{
int x = -1, y = 2, z = -3;
{
std::cout << "lvalue" << std::endl; typedef int T;
list2<T> l2 = list0<T>( x )( y )( z );
if( &l2.head() != &z ){ std::cout << l2.head(); }
if( &l2.tail().head() != &y ){ std::cout << l2.tail().head(); }
if( &l2.tail().tail().head() != &z ){ std::cout <<
l2.tail().tail().head(); }
}
{
std::cout << "rvalue" << std::endl; typedef int const T;
list2<T> l2 = list0<T>( -1 )( 2 )( -3 );
if( l2.head() != -3 ){ std::cout << l2.head(); }
if( l2.tail().head() != 2 ){ std::cout << l2.tail().head(); } //
Access violation, some not all compilers
if( l2.tail().tail().head() == -1 ){ std::cout <<
l2.tail().tail().head(); }
// I suspect it breaks the [bound temporary persists for the lifetime
of the reference] rule.
// Can anyone confirm or deny with certainty?
}
return 0;
}
Thanks.
conforming with C++ rules or not.
#include <iostream>
template<typename T> struct head_holder
{
explicit head_holder(T& t) : head_( &t ){}
T& head() const{ return (*this->head_); }
private:
T* head_;
};
template<typename T> struct tail_holder
{
tail_holder(T const& t) : tail_( t ){}
typedef T const& result_type;
T const& tail()const{ return this->tail_; }
private:
T const& tail_;
};
template<typename T> struct list1;
template<typename T> struct list0 : head_holder<T>
{
list0(T& x) : head_holder<T>( x ){}
list1<T> operator()(T& y)const{
return list1<T>(*this, y);
}
};
template<typename T> struct list2; template<typename T> struct list1 :
head_holder<T>
{
typedef list0<T> list0_; typedef tail_holder<list0_ >
tail_holder_;
list1(const list0_& t, T& y) : head_holder<T>( y ),
tail_holder( t ){}
list2<T> operator()(T& z)const{ return list2<T>(*this, z); }
typename tail_holder_::result_type tail()const{
return this->tail_holder.tail();
}
private:
tail_holder_ tail_holder;
};
template<typename T> struct list2 : head_holder<T>
{
typedef list1<T> list1_; typedef tail_holder<list1_ >
tail_holder_;
list2(const list1_& t, T& y) : head_holder<T>( y ),
tail_holder( t ){}
list2<T> operator()(T& z)const{ return list2<T>(*this, z); }
typename tail_holder_::result_type tail()const{
return this->tail_holder.tail();
}
private:
tail_holder_ tail_holder;
};
template<typename T> list0<T> make( T& x ){ return list0<T>( x ); }
template<typename T>list0<T const> make( T const& x ){ return list0<T
const>( x ); }
int main()
{
int x = -1, y = 2, z = -3;
{
std::cout << "lvalue" << std::endl; typedef int T;
list2<T> l2 = list0<T>( x )( y )( z );
if( &l2.head() != &z ){ std::cout << l2.head(); }
if( &l2.tail().head() != &y ){ std::cout << l2.tail().head(); }
if( &l2.tail().tail().head() != &z ){ std::cout <<
l2.tail().tail().head(); }
}
{
std::cout << "rvalue" << std::endl; typedef int const T;
list2<T> l2 = list0<T>( -1 )( 2 )( -3 );
if( l2.head() != -3 ){ std::cout << l2.head(); }
if( l2.tail().head() != 2 ){ std::cout << l2.tail().head(); } //
Access violation, some not all compilers
if( l2.tail().tail().head() == -1 ){ std::cout <<
l2.tail().tail().head(); }
// I suspect it breaks the [bound temporary persists for the lifetime
of the reference] rule.
// Can anyone confirm or deny with certainty?
}
return 0;
}
Thanks.