Reputation:
The standard N4296::3.3.4/1 [basic.scope.proto]
:
In a function declaration, or in any function declarator except the declarator of a function definition (8.4), names of parameters (if supplied) have function prototype scope, which terminates at the end of the nearest enclosing function declarator.
I tried the following examples:
1.
template<const int a>
class A{ };
const int a = 4;
A<a> b; // OK
void foo(const int a = 4, A<a>); //non-type template argument is
//not a constant expression
2.
void foo(const int a = 4, int b = a); //default argument references parameter 'a'
How can we use this scope's feature? What is it introduced for?
Upvotes: 1
Views: 83
Reputation: 137320
To add to user657267's example, trailing-return-types often depend on this feature:
template<class A, class F>
auto foo(const A& a, const F& f) -> decltype(f(a));
Upvotes: 1
Reputation: 21000
Here's a contrived example:
void foo(overly::long_type::which_should_be_a_typedef_anyway a, decltype(a) b); // fine
decltype(a) c; // oops, a not declared
Upvotes: 4
Reputation: 753675
I think the point of this is to say that the following code is valid:
extern int somefunc(int a, char *b, int c);
int somefunc(int, char *, int);
int somefunc(int number, char *bytes, int ipv4_address)
{
…
}
The name a
, b
and c
lose their significance at the closing parenthesis of the extern
declaration. Within the declarator, the names are significant to the extent that int somefunc(int a, char *a, int a);
is invalid because the same name a
is used where distinct identifiers are required.
The names number
, bytes
and ipv4_address
do not lose their significance at the close parenthesis because that is the 'declarator of a function definition'; they become the names of variables within the function.
Note that Stroustrup explicitly declined to tie parameter names in function declarations to parameter names in function definitions. There's a section in Design and Evolution of C++ that discusses this.
Upvotes: 3