Boost logo

Boost :

Subject: Re: [boost] Compiler error in gcc3+ involving template template parameter and default parameters
From: Edward Diener (eldiener_at_[hidden])
Date: 2011-01-16 21:34:41


On 1/16/2011 5:55 PM, Brent Spillner wrote:
> On 01/16/2011 8:34 AM, Edward Diener wrote:
>> That is very nice to say, but the library is for Boost which does try to
>> still support gcc3+. I know it compiles without error in gcc4+. I should
>> have been more explicit when I notated 'gcc3+' to ex0plain that I meant
>> gcc3 versions and not gcc4 versions.
>
> I would have dropped the '+' ;-) I'm all about supporting the widest
> possible variety of compilers, but note that the last GCC 3 release
> was nearly five years ago. I'm sure that there are plenty of other
> things in Boost that it can't handle.

Of course but I felt that some people are still using gcc3 compilers and
I should try to satisfy them. After all its not like VC6, which no one
in his right mind would pay any attention to anymore. Even VC7.1 will
not work entirely with my implementation and I refuse to try to get it
to work.

>
>> Those are just specializations of:
>>
>> template<class T>
>> struct eval;
>>
>> There is no reason SFINAE should be involved.
>
> It's the same principle; rather than attempting to substitute class
> members, the compiler is substituting the parameters of the template
> class F. At any rate, I don't know another name for the concept.

I think the name of the concept is just picking the correct
specialization, which of course gcc3 is failing to do by claiming
ambiguity where it does not exist.

>
>>> 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 {};
>>
>> I do not follow this. Your is_unary and is_binary are typedefs within
>> 'ptmf' and 'other' templates.
>
> The idea was to give g++ a little more information to help resolve the
> eval<> ambiguity; when 'ptmf' is substituted for 'F', there is no
> nested ::is_binary and the second specialization cannot apply, but the
> first specialization resolves and in fact yields the same type that it
> would have without the '::is_unary'. Unfortunately, that doesn't seem
> to be enough help for GCC 3.4.6.

I understand what you meant to do now.

>
> I did, however, get your example to compile by refactoring a bit: if
> you change the template parameters for ptmf to 'template<class T,
> class P = noparam, class Unused = noparam>', then you can eliminate
> the first specialization of eval<> but provide additional
> specializations for the cases where P2 is noparam or P1 and P2 are
> both noparam, e.g.
>
> struct nullary_op {}; struct unary_op {}; struct binary_op {};
>
> template<template<class,class> class F, class P1, class P2>
> struct eval<F<P1,P2> > :
> F<typename P1::type,typename P2::type> { typedef binary_op category; };
>
> template<template<class,class> class F, class P1>
> struct eval<F<P1,noparam> > :
> F<typename P1::type,noparam> { typedef unary_op category; };
>
> template<template<class,class> class F>
> struct eval<F<noparam,noparam> > :
> F<noparam,noparam> { typedef nullary_op category; };
>
> where ::category is just a type tag to help you differentiate between
> the types of eval<> elsewhere in the framework. This compiles as-is
> under GCC 3.4.6, and requires that you change the first declaration of
> eval ('template<class F> struct eval;') to a concrete definition
> ('template<class F> struct eval {};') under GCC 4.4.4 and 4.5.2 (also
> legal under 3.4.6.) I don't know how well this solution fits into the
> rest of your library, but I hope it at least provides some ideas.

Yes I understand. Thanks for the alternative ! I am looking at some
others but yours is a good possibility for gcc3.


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