|
Boost Users : |
From: Aleksey Gurtovoy (alexy_at_[hidden])
Date: 2003-07-10 13:17:07
Brian Simpson wrote:
> I want to express a "type-mapping" scheme. My implementation idea is
this:
> have the user define an MPL sequence comprised exclusively of std::pair
> derivations. He can then instantiate my template class with his sequence
as
> the argument. My template then derives two MPL sequences, one containing
> the "first" types, the other containing the "second" types.
> Here is the attempt:
> <code>
> namespace ls
> {
> using namespace boost::mpl;
> using namespace placeholders;
>
> template <class TypePairSequence>
> struct list_splitter
> {
> template <class STDPAIR>
> struct first_type
> {
> typedef typename STDPAIR::first_type type;
> };
> template <class STDPAIR>
> struct second_type
> {
> typedef typename STDPAIR::second_type type;
> };
>
> typedef
> typename
> transform
> <
> TypePairSequence
> , first_type<_1>
> >
> ::type
> first_types;
>
> typedef
> typename
> transform
> <
> TypePairSequence
> , second_type<_1>
> >::type
> second_types;
> };
>
> }//end namespace ls
> </code>
>
> Here is an attempt to instantiate:
> 1> typedef boost::mpl::list< std::pair<long, short>, std::pair<char,
double>
> > associated_types;
> 2> typedef ls::list_splitter<associated_types> split_associated_types;
> 3> typedef split_associated_types::first_types first_types;
> 4> typedef split_associated_types::second_types second_types;
> 5> typedef boost::mpl::at_c<first_types, 0>::type first_first_t;
> Code lines 1-2 compile fine. When I add line 3, I get the following
error:
> "no type named `first_type' in `struct boost::mpl::arg<1>'".
[...]
> I'm sure I'm overlooking something simple. Could someone point me in the
> right direction?
> I'm using gcc3.2.2 on Solaris 9.
Brian, I don't have access to gcc 3.2.2 at the moment, but it looks like
they are still not able to handle the class template arity issues
correctly (your example also fails with an internal compiler error on 3.2).
The essence of the issue is that gcc adopts a non-standard extension
under which two class template specializations like these
template< typename T > struct lambda { typedef T type; };
template<
template< typename > class F
, typename T1
>
struct lambda< F<T1> >
{
};
template<
template< typename, typename > class F
, typename T1, typename T2
>
struct lambda< F<T1,T2> >
{
};
cause an ambiguity when instantiated on another class template with one
or more default template parameters:
template< typename T1, typename T2 = void > struct my {};
lambda< my<int> > l; // error here
Basically, the extension is non-conforming and IMO is a bug, but
for some reason gcc developers have been reluctant to admit so ;).
Anyway, to make the long story short, MPL tries to deal with the
ambiguity above by using a sophisticated method for determining the
"true" template arity even under these unfriendly conditions - but due
to other compiler bugs it still didn't always work properly in 3.2.
Seems like in 3.2.2. things didn't change for the better.
The good news is that if you re-write your metaprogram as follows, it
will work:
#include "boost/mpl/list.hpp"
#include "boost/mpl/lambda.hpp"
#include "boost/mpl/transform.hpp"
#include "boost/mpl/select1st.hpp"
#include "boost/mpl/select2nd.hpp"
#include "boost/mpl/pair.hpp"
namespace ls
{
using namespace boost::mpl;
using namespace placeholders;
template <class TypePairSequence>
struct list_splitter
{
typedef
typename
transform
<
TypePairSequence
, boost::mpl::select1st<_1>
>
::type
first_types;
typedef
typename
transform
<
TypePairSequence
, boost::mpl::select2nd<_1>
>::type
second_types;
};
}//end namespace ls
typedef boost::mpl::list< boost::mpl::pair<long, short>,
boost::mpl::pair<char, double> > associated_types;
typedef ls::list_splitter<associated_types> split_associated_types;
typedef split_associated_types::first_types first_types;
If you want to know more details, just ask :).
HTH,
Aleksey
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