Question

According to the C++ Standard, function parameter's name is parsed by a declarator-id, and a declarator-id can also be a qualified name. That means, the following code is perfectly valid (if I've understood the relevant sections from the Standard correctly):

template<class T>
struct Sample
{
    int fun(int T::count); //T::count is qualified variable name
};

My question basically is, why would anyone write such code? In what situations, the use of qualified name (in function parameter-list) can be advantageous?


EDIT:

It seems I understood the sections incorrectly. Instead of the above code, we can probably write the following code (as per the C++ standard):

template<class T>
struct sample
{
  void fun(int arr[T::count]);
};

gcc-4.3.4 compiles it perfectly. But then, I'm not totally satisfied, because T::count is not a parameter anymore (I guess).

Was it helpful?

Solution

It's invalid. The syntax allows arbitrary declarators, but 8.3.5p8 says

An identifier can optionally be provided as a parameter name; if present in a function definition (8.4), it names a parameter (sometimes called “formal argument”)

Edit Another quote which syntactically constraints declarators (8.3p1, [dcl.meaning]):

Each declarator contains exactly one declarator-id; it names the identifier that is declared. The id-expression of a declarator-id shall be a simple identifier except for the declaration of some special functions (12.3, 12.4, 13.5) and for the declaration of template specializations or partial specializations (14.7). A declarator-id shall not be qualified except for the definition of a member function (9.3) or static data member (9.4) or nested class (9.7) outside of its class, the definition or explicit instantiation of a function, variable or class member of a namespace outside of its namespace, or the definition of a previously declared explicit specialization outside of its namespace, or the declaration of a friend function that is a member of another class or namespace (11.4).

So in a parameter declaration, you must not use qualified names.

Edit: In the edited form, the function parameter type decays to an int*, even before a test is being made whether T::count actually exists and is an integer constant. If you want an example where a qualified name in such a signature would do something meaningful, consider

template<class T>
struct sample
{
  void fun(int S=T::count);
};

When fun gets called without parameter, the compiler needs to determine the default argument, which then fails if T does not have a count member, or that cannot be converted to int.

OTHER TIPS

As far as I understand your code is ill formed because

$8.3/1 : When the declarator-id is qualified, the declaration shall refer to a previously declared member of the class or namespace to which the qualifier refers, and the member shall not have been introduced by a using-declaration in the scope of the class or namespace nominated by the nested-name-specifier of the declarator-id. [Note: if the qualifier is the global ::scope resolution operator, the declarator-id refers to a name declared in the global namespace scope. ]

P.S: I am not 100% sure. Please correct me if I am wrong. :)


In what situations, the use of qualified name (in function parameter-list) can be advantageous?

Read Items 31 and 32 from Exceptional C++ by Herb Sutter. Both the items deal with Koenig lookup and the Interface principle.

It seems I understood the sections incorrectly. Instead of that code, we can probably write the following code (as per the C++ standard):

template<class T>
struct sample
{
  void fun(int arr[T::count]);
};

gcc-4.3.4 compiles it perfectly. But then, I'm not totally satisfied, because T::count is not a parameter anymore (I guess).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top