Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does a namespace-scope constructor definition require a class-qualified identifier?

Here's something we all learned on Day 1 of C++, which we take for granted but doesn't clearly follow from the wording of the Standard.

Given a class S, we can define its constructor

struct S { S(); };
S::S() { … }

But the Standard seems to allow this just as well:

struct S { S(); };
S() { … }

Qualifying the name of a class with itself is always allowed but always redundant. For example S::S::S::S() { … } is also a valid declaration. If S::S is, why not plain S?

From C++11 §12.1/1,

Constructors do not have names. A special declarator syntax is used to declare or define the constructor. The syntax uses:

— an optional decl-specifier-seq in which each decl-specifier is either a function-specifier or constexpr,

— the constructor’s class name, and

— a parameter list

in that order.

This applies equally to class or namespace scope. There is a special rule about namespace scope, §9.3/5,

If the definition of a member function is lexically outside its class definition, the member function name shall be qualified by its class name using the :: operator.

However, constructors do not have names, so this doesn't apply, right? Moreover, there's no reason to require the qualification, because there is no syntactic ambiguity. A function declared with no return type and a class-name for an identifier is always a syntax error under currently observed rules. Right?

Not that we should start writing code with the qualification omitted, but is there a reason that no compiler accepts this, or is it just tradition?

like image 631
Potatoswatter Avatar asked Aug 19 '11 09:08

Potatoswatter


People also ask

What is namespace how will you define a namespace in C++?

A namespace is a declarative region that provides a scope to the identifiers (the names of types, functions, variables, etc) inside it. Namespaces are used to organize code into logical groups and to prevent name collisions that can occur especially when your code base includes multiple libraries.

How does a constructor work in C++?

A constructor in C++ is a special 'MEMBER FUNCTION' having the same name as that of its class which is used to initialize some valid values to the data members of an object. It is executed automatically whenever an object of a class is created.

What is the scope of a using declaration?

Using-declarations can be used to introduce namespace members into other namespaces and block scopes, or to introduce base class members into derived class definitions, or to introduce enumerators into namespaces, block, and class scopes (since C++20).

What is global namespace in C++?

Beginning of C++ only. Global scope or global namespace scope is the outermost namespace scope of a program, in which objects, functions, types and templates can be defined. A name has global namespace scope if the identifier's declaration appears outside of all blocks, namespaces, and classes.


1 Answers

Yes, it says that,

If the definition of a member function is lexically outside its class definition the member function name shall be qualified by its class name using the :: operator.

But it doesn't says that member function w/o name shall not be qualified by its class name. Does it? ;)

That seems to lead to an uncertain area depending on implementations. However, the form of A::A is defined by the Standard.

5.1 Primary Expressions

Where class-name :: class-name is used, and the two class-names refer to the same class, this notation names the constructor..

As to whether A(){..} is allowed or not, I guess there is no reason to do it conventionally(Is there ANY C++ compiler allow it?? AFAIK, nope):

  1. Since constructor is a special member function, the way of A::A(){..} is more consistent with other member functions. Why borther allow it to behave specially? That's probably not worth the effort.

  2. No one wants to run the risk of writing non-compliant code that's not explicitly stated in the Standard.

like image 96
Eric Z Avatar answered Sep 17 '22 13:09

Eric Z