Re: [boost] Compiler error in gcc3+ involving template template parameter and default parameters

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.

On 1/16/2011 7:06 AM, Brent Spillner wrote:
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.
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 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.
Those are just specializations of: template<class T> struct eval; There is no reason SFINAE should be involved.
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 {};
I do not follow this. Your is_unary and is_binary are typedefs within 'ptmf' and 'other' templates.
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.
What is the purpose of your ::is_unary and ::is_binary typedefs ?
participants (2)
-
Brent Spillner
-
Edward Diener