The fairly simple code below, involving template template parameters and
default parameters compiles with an error in gcc3+ compilers but
compiles without error in gcc4+ and up, and with other conforming compilers:
"template<class T>
struct eval;
template
<
template<class> class F,
class P1
>
struct eval<F<P1> > :
F<typename P1::type>{};
template
<
template<class,class> class F,
class P1,
class P2
>
struct eval<F<P1,P2> > :
F<typename P1::type,typename P2::type>{};
struct noparam
{
typedef noparam type;
};
template
<
class T,
class P = noparam
>
struct ptmf
{
typedef int type;
};
template
<
class T,
class P = noparam
>
struct tkf :
eval<ptmf<T,P> >{};
template <class T>
struct ATemplate
{
typedef T type;
};
int main()
{
tkf<ATemplate<int> > aVar;
return 0;
}"
The command line in MingW on Windows is:
"g++" -ftemplate-depth-128 -O0 -fno-inline -Wall -g -c "TestGcc3.cpp"
The error message is:
"TestGcc3.cpp: In instantiation of `tkf<ATemplate<int>, nopar
am>':
TestGcc3.cpp:52: instantiated from here
TestGcc3.cpp:42: error: ambiguous class template instantiatio
n for `struct eval<ptmf<ATemplate<int>, noparam> >'
TestGcc3.cpp:19: error: candidates are: struct eval<F<P1, P2>
>
TestGcc3.cpp:10: error: struct eval<F<P1> >
TestGcc3.cpp:42: error: invalid use of undefined type `struct
eval<ptmf<ATemplate<int>, noparam> >'
TestGcc3.cpp:2: error: declaration of `struct eval<ptmf<ATemp
late<int>, noparam> >'
TestGcc3.cpp: In function `int main()':
TestGcc3.cpp:52: warning: unused variable 'aVar'"
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:
tkf<ATemplate<int>,ATemplate<int> > aVar;
the compile is successful and there is no error. This is of course a
very simplified illustration of much more complicated code and
maintaining default parameters within the more complicated situation is
a much cleaner syntax than the alternative.
If you ask why I am trying to get this to work under gcc3 it is because
I am creating a library for Boost and would like to still support gcc3+
with my library.