Boost logo

Boost :

Subject: Re: [boost] Compiler error in gcc3+ involving template template parameter and default parameters
From: Brent Spillner (spillner_at_[hidden])
Date: 2011-01-16 07:06:20


On 01/15/2011 10:41 PM, Edward Diener wrote:
>I am showing this gcc3 bug just in case any other Boost developer has
>run into it and knows some easy workaround. It will save me some time as
>the workaround in the actual case, which is more complicated, is very
>laborious as I envision it ( I have not yet attempted to code up the
>laborious workaround ). I ran into this type of case as the problem in
>my tti library which is keeping it from supporting gcc3+.

Your sample code compiles for me without errors or warnings (other
than the unused variable) under GCC 4.4.4 and 4.5.2. Is there a
particular GCC version that you need to support? In my experience GCC
versions before 4.4 have badly broken template support and should be
avoided if at all possible.

>I am looking for a workaround for gcc3+ compilers which does not involve
>getting rid of the default parameters. If I remove the default
>parameters, and change the instantiation of tkf to:

I would start by removing the "template<class>" / "template<class,
class>" specifications on the dependent types F. Those may be what
sent you into a poorly-tested and bug-ridden corner case in whichever
release of GCC you're using, and should be unnecessary--- the compiler
will not be able to instantiate the base class F<typename P1::type>
when F requires two parameters, nor F<typename P1::type, typename
P2::type> when it accepts only one, and should SFINAE to the proper
case.

If you do need those explicit constraints on F to work around problems
in GCC 3 or another compiler, and it's feasible to nest a new typedef
into all types that are legal as the F argument of eval<>, you could
construct something like

template <class T, class P = noparam>
struct ptmf {
  typedef int type;
  typedef ptmf<T, P> is_unary;
};

template <class T, class P1, class P2>
struct other {
  typedef int type;
  typedef other<T, P1, P2> is_binary;
};

template <template<class> class F, class P1>
struct eval<F<P1> > : typename F<typename P1::type>::is_unary {};

template <template<class,class> class F, class P1, class P2>
struct eval<F<P1, P2> > : typename F<typename P1::type, typename
P2::type>::is_binary {};

If you need to support F types to which you can't add typedefs, you'll
have to use the template <class F> struct F_traits{} pattern to
provide ::is_unary, ::is_binary, etc.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk