$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Gennaro Prota (gennaro_prota_at_[hidden])
Date: 2002-08-03 12:58:09
On Sat, 3 Aug 2002 08:19:10 -0400, "David Abrahams"
<dave_at_[hidden]> wrote:
>> > What about adding a new config macro, e.g.
>> > BOOST_NO_MULTIPLE_DEFAULT_TEMPLATE_ARGUMENTS, that deals with this?
>> >
>> > <snip...>
>> >
>> > I'm not sure about the situations in which the problem reveals itself,
>> > so maybe the name of the macro isn't even appropriate but, regardless
>> > of the name, I think some macro is useful. Opinions?
>>
>> Looks reasonable, I'll try and add it some time over the next few days
>> unless there are any other comments.
>
>Well, I didn't think I was going to have to say anything, but the name at
>least is crazy. Normally there's no problem in using multiple default
>arguments with that compiler, and we do it all the time in boost libs.
>Possibly this problem occurs only when one default argument expression uses
>the type of another argument with a default?
Neither :-) The issue is that I haven't found any official
documentation that says when the problem occurs.
parameters with 2 defaults, it seems (*seems*!) that, regardless of
whether a default expression references one of the other parameters,
the problem doesn't occur when
a) either the first encountered declaration of the template is a
definition; e.g.:
// ok
//
template <class A = int, class B = A>
class Test {};
// ok too
//
template <class T>
class traits {};
template <class A = int, class B = traits<A> >
class Test {};
b) or the declarations and the definition all give the (same) default
arguments:
// ok
//
template <class A = int, class B = double>
class Test;
template <class A = int, class B = double>
class Test {};
Instead these all give an error at the point of definition ("C2984:
'Test' : template parameters '' and '' do not match"):
// (1)
//
template <class A = int, class B = A>
class Test;
template <class A, class B>
class Test {};
// (2)
//
template <class A, class B>
class Test;
template <class A = int, class B = double>
class Test {};
// (3)
//
template <class T>
class traits {};
template <class A = int, class B = traits<A> >
class Test;
template <class A, class B>
class Test {};
Note also, that this passes:
// 1 default argument - ok
//
template <class A, class B = A>
class Test;
template <class A, class B>
class Test {};
If the above circumscribes the problem correctly, for libraries that
use the classical xxx_fwd.hpp there are at least 3 choices (let's call
M a suitable macro):
1. not using default arguments at all for compiler(s) that have/has
this problem
// in the declaration
# ifdef M
template <class A, class B>
# else
template class A = int, class B = traits<A>
#endif
class Test;
2. Using only the number of defaults that the compiler accepts (well,
it could depend on the compiler but I don't know if there are others
with the same bug)
Example similar to 1.
3. specifying defaults in the definition too:
// in the definition
//
# ifdef M
template <class A = int, class B = traits<A> >
# else
template <class A, class B>
# endif
class Test {};
This has the draw back that eventually a change of the default
arguments has to be done in more than one point, but I wouldn't be
worried for that. For most libraries, changing the default arguments
would break user code. Option 3 is also feasible without any macro, of
course.
In any case, it would be nice if someone that regularly uses VC had
some more information about the problem. Any hints?
Genny.