Boost logo

Boost :

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.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk