Q about default function parameters

B

Bob Hairgrove

Why can I do this:

template<typename A, typename B=A>
struct X { /*...*/ };

whereas this gives me an error about an undeclared identifier with
MSVC++ 7.1:

struct A
{ A(int arg1, int arg2=arg1); };

Now I know that the C++ standard says "you can't do that" (section
8.3.6 paragraph 9), but from a parsing standpoint, it seems like if
the compiler can handle the template parameter, it should have no
problem with the function parameter?

Thanks.
 
A

Alf P. Steinbach

* Bob Hairgrove:
Why can I do this:

template<typename A, typename B=A>
struct X { /*...*/ };

whereas this gives me an error about an undeclared identifier with
MSVC++ 7.1:

struct A
{ A(int arg1, int arg2=arg1); };

Now I know that the C++ standard says "you can't do that" (section
8.3.6 paragraph 9), but from a parsing standpoint, it seems like if
the compiler can handle the template parameter, it should have no
problem with the function parameter?

I think you should post this question to [comp.std.c++].

The paragraph you refer to says it's because the function argument evaluation
order is not defined (template parameters have no such problem).

I.e. if 'arg2' were evaluated first it would refer to an indeterminate or
non-existent value, the way the language is.

However, on the other hand, if it were allowed it could simply _restrict_ the
evaluation order, and with one exception I see no particular problem with
that. The exception: in C, for stack-based argument passing, arguments are
conventionally pushed (and hence, for efficiency, evaluated) right to left, in
order to support variable number of arguments, the C++ "..." notation. But as
I see it this is not a showstopper problem, because the non-"..." (first N)
arguments can be pushed and evaluated left to right, after pushing and
evaluating the "..." arguments right to left, and with this scheme the
function implementation can refer to the non-"..." arguments at fixed offsets
from the stack pointer, just as before.

On the third hand, you can obtain just about the same effect by writing

struct A
{
A( int a1 ): myX( a1 ), myY( a1 ) {}
A( int a2, int a2 ): myX( a1 ), myY( a2 ) {}
...
};

which does suffer a little from the lack of constructor forwarding, but if or
when we get constructor forwarding that will perhaps completely solve this.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top