2

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).

Dan Nissenbaum
  • 13,558
  • 21
  • 105
  • 181
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • For reference: http://stackoverflow.com/questions/4347730/use-of-typename-keyword-with-template-function-parameters/4348172#4348172 – Johannes Schaub - litb Dec 11 '10 at 16:04
  • So what's the question now? Are you still interested in finding out why anybody would want to do that? – Martin v. Löwis Dec 11 '10 at 17:22
  • @Martin : if you're referring to the edited part of my post, then yes, I would like to hear something from you and others, especially why would anyone use `arr[T::count]`? – Nawaz Dec 11 '10 at 17:37

3 Answers3

2

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.

Martin v. Löwis
  • 124,830
  • 17
  • 198
  • 235
  • @Martin... I didn't really understand the quotation. Could you please explain that? – Nawaz Dec 11 '10 at 15:17
  • It says "yes, you can have a name in a parameter, but it must be an identifier (i.e. it must be unqualified). – Martin v. Löwis Dec 11 '10 at 15:25
  • @Martin : I don't think it says "but it must be an identifier (i.e it must be unqualified)". Also, it contradicts the grammar of *parameter-declaration-clause*. – Nawaz Dec 11 '10 at 15:49
  • 2
    It's explicitly forbidden by 8.3/1: "A declarator-id shall not be qualified except for the definition of a member function (9.3) or static data member (9.4) outside of its class, the definition or explicit instantiation of a function or variable member of a namespace outside of its namespace, or the definition of an explicit specialization outside of its namespace, or the declaration of a friend function that is a member of another class or namespace (11.4)." – Johannes Schaub - litb Dec 11 '10 at 16:13
  • How else would you interpret "an identifier can be provided", if they don't mean that what is optionally be provided must be an identifier? I fail to see how to contradicts: declarator->direct->declarator->declarator-id->id-expression->unqualified-id->identifier. – Martin v. Löwis Dec 11 '10 at 16:19
  • @Martin and @Johannes : thanks for the [updated] post and valuable comments. I'm trying to understand them. Hope it'll clear my doubts. :-) – Nawaz Dec 11 '10 at 16:41
  • @Martin : thanks for the update in your post. I think, it answers my question quite satisfactorily. :-) – Nawaz Dec 11 '10 at 18:03
1

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.

Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345
  • thanks for the post with reference. I'll look into this & related points, and try to understand them. – Nawaz Dec 11 '10 at 16:36
0

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).

Nawaz
  • 353,942
  • 115
  • 666
  • 851