Multiple declarations in C ++

In [basic.scope.declarative] p4 reads

Given a set of declarations in one declarative field, each of which indicates the same unqualified name, - (4.1) they all refer to the same entity ...

A naive reading may mean that the following code may be valid, because "both declarations refer to the same entity":

int x; int x; 

Then we can recall one rule of definition [basic.def.odr] p1. The above reasoning may only apply to declarations not to definitions. This difference is outlined in [basic.def] p2. For example, the following code is certainly valid:

 extern int x; extern int x; 

The last example in [basic.def] p2 assumes that the following code must be valid, but it does not compile (using MSVC2015).

 struct B { int y; }; struct D : B { using B::y; using B::y; }; 

Where is the problem?


Error message

use-declarations for 'B :: y' cannot coexist with an existing declaration of use for 'B :: y'

+4
source share
2 answers

This example from [namespace.udecl] p10 is exactly the same as yours:

 struct B { int i; }; struct X : B { using B::i; using B::i; // error: double member declaration }; 

The error is supported by [class.mem] p1:

A member should not be declared twice in the member specification, except that a template of a nested class or member class can be declared and then later defined, and moreover, an enumeration can be entered with an opaque declaration, and later updated using an enumerator specifier.

So you're on the right track. Several declarations are in order if they do not violate other rules (for example, one definition, member specifications, etc.).

For example, the following:

 struct X; struct X; 

Or a more complex example:

 struct X { struct A; struct A { int y; }; }; struct X; struct X::A; 
+5
source

You almost answered your question, referring to namespace.udecl / 10. The example below (N3936) shows the place where several equivalent using -decisions are allowed:

 namespace A { int i; } namespace A1 { using A::i; using A::i; // OK: double declaration } void f() { using A::i; using A::i; // error: double declaration } struct B { int i; }; struct X : B { using B::i; using B::i; // error: double member declaration }; 

Multiple using -decisions for a function in the namespace and block area are also allowed. As for why they are not allowed for variables (objects) in the block area, I have no idea. Several equivalent declarations of participants are probably prohibited for two reasons:

  • great potential for initialization order errors
  • this was not necessary historically, because the bodies of methods defined by the built-in “see” members declared later in the same class (with the introduction of decltype in C ++ 11, this reason is no longer final)
0
source

All Articles