
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.