template<class A, class B>
class Arg {
public:
Arg() {};
};
template<class A, class B>
class User {
public:
User(const char* username,
Arg<A,B> arg = Arg<A,B>(),
bool flag = false)
{
};
};
gcc fails to compile it. The error output is:
ex2.cpp:12: error: expected `,' or `...' before '>' token
ex2.cpp:12: error: missing `>' to terminate the template argument list
ex2.cpp:12: error: wrong number of template arguments (1, should be 2)
ex2.cpp:3: error: provided for `template<class A, class B> class Arg'
Taking out the defaulting of the template argument makes the problem
go away.
This example, is a cutdown from some legacy code I am looking it. I am
trying to get it to compile with gcc. It compiles with Visual Studio
2005, but then lots of illegal C++ is let through with *that*
compiler.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
It compiles for me with g++ 4.4.0 - which version of g++ are you using?
Neil Butterworth
> I cannot see what is wrong with the code below:
>
> template<class A, class B>
> class Arg {
> public:
> Arg() {};
> };
>
> template<class A, class B>
> class User {
> public:
> User(const char* username,
> Arg<A,B> arg = Arg<A,B>(),
> bool flag = false)
> {
> };
> };
>
> gcc fails to compile it. The error output is:
>
> ex2.cpp:12: error: expected `,' or `...' before '>' token
> ex2.cpp:12: error: missing `>' to terminate the template argument list
> ex2.cpp:12: error: wrong number of template arguments (1, should be 2)
> ex2.cpp:3: error: provided for `template<class A, class B> class Arg'
>
> Taking out the defaulting of the template argument makes the problem
> go away.
>
You can fix it with wrapping (...) around the default argument "Arg<A,B>()".
The problem is that in default arguments, names from members of the class
are found even if they're declared afterwards. With older GCC, this
presented a problem that escaped into your code too: GCC always parsed this
as
User(
/* first: param: */ const char* username
/* second param: */ , Arg<A,B> arg = Arg<A,
/* third param: */ , B>(),
/* fourth param: */ , bool flag = false)
See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#325 . It was
fixed in some more recent GCC to compile your code.
3.4.4-3. I realise this is quite old. It is where gcc is in cygwin at
the moment. AFAIK the only way to get a more recent one is to build it
from the source. I might just do that.
So it looks like the code is legal than. Good. I must admit, I
couldn't see what was wrong with it.
-Andrew M.
I see neither a problem for theoretical reasons
nor from practical tests with a most recent gcc
4.4.1. Either you are using an older/buggy compiler
or the actual reason for the compiler error
has been eliminated during code simplification.
In my test I instantiated the User template via
User<int, bool> u("");
HTH & Greetings from Bremen,
Daniel Kr�gler
Or to give up on Cygwin and use the MinGW GCC port instead. MinGW keeps
up with GCC changes pretty well, particularly if you use the Twilight
Dragon branch. I gave up on Cygwin several years ago, using MSYS and
GnuWin32 for tools etc.) and haven't looked back.
Neil Butterworth
>> It compiles for me with g++ 4.4.0 - which version of g++ are you using?
>
> 3.4.4-3. I realise this is quite old. It is where gcc is in cygwin at
> the moment. AFAIK the only way to get a more recent one is to build it
> from the source. I might just do that.
On the latest version of GCC under Cygwin, invoking "g++" does give you
version 3.4.4. But, if you invoke "g++-4" instead, you get version 4.3.2.
If you have g++ installed, you probably already have g++-4 installed too.
4.1.0 (at least shipped with SLES 10 also has the bug.
I can't check right now but I don't think Cygwin 1.5 has upgraded past
3.4.4. It's basically frozen while the work goes into 1.7 which does
have both 3 and 4. If you install 1.7, which is pretty stable now, be sure to
read up on "alternatives". That information covers the proper way to
manage GCC 3 vs 4.