Boost logo

Boost Users :

From: Daniel Krügler (dsp_at_[hidden])
Date: 2005-08-10 02:12:08


(Note: The following contribution is essentially a copy of
a former one, which was, due to several administrative problems
on my side, probably overlooked by the majority of concerned
programers)

Dear Boosters,

its quite a while that I could participate in this newsgroup, so maybe
my request is ol' stuff and has been answered 100 times. In case of that
I apologize for the following question:

I observe that boost::tuple::length in version 1.32+1.33RC2 exist two
template
specializations for empty tuples, namely

template<>
struct length<tuple<> > {
       BOOST_STATIC_CONSTANT(int, value = 0);
};

template<>
struct length<null_type> {
       BOOST_STATIC_CONSTANT(int, value = 0);
};

which lead to the unexpected effect that e.g.

typedef const tuple<> ConstEmptyTuple;
int k = length<ConstEmptyTuple>::value;

(modulo namespace issues) does not compile. The reason is obvious,
because deduction of boost::tuples::length<ConstEmptyTuple>
extracts "const tuple<>", which leads to the generic template
definition:

template<class T>
struct length {
       BOOST_STATIC_CONSTANT(int, value = 1 + length<typename
T::tail_type>::value);
};

which does not compile in this case, because const oost::tuples::tuple<>
has no tail_type. Similar situations arise for const null_type arguments
and corresponding volatile variants thereof.

To my humble opinion tuples::length should work independent of cv
qualification of the template arguments, but this route should of course
be gone in accordance to similar situations of "template predicates" in
boost::mp/type_traits.

One further indirection and usage of boost::remove_cv<T> could
simply resolve the described problem, such as:

// Define length_impl + 2 specialisation for tuple<> and null_type as
// currently done for length
namespace details {

template <typename T>
struct length_impl
{
        .. // as before;
};

template <>
struct length_impl<null_type>
{
        .. // as before;
};

template <>
struct length_impl<tuple<null_type, ...> >
{
        .. // as before;
};

}

// One single - not specialized - length template handling all cases:

template <typename T>
struct length
{
         static const int value = details::length_impl<
           typename ::boost::remove_cv<T>::type >::value;
};

What do you think?

Greetings from Bremen,

Daniel Krügler


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net