Unless otherwise specified, two declarations cannot (re)introduce the same entity. The program is ill-formed if such declarations exist.
Corresponding declarations
Two declarations correspond if they (re)introduce the same name, both declare constructors, or both declare destructors, unless
either is a
,
one declares a type (not a
) and the other declares a variable, non-static data member other than of an
, enumerator, function, or function template, or
each declares a function or function template and they do not declare corresponding overloads.
Corresponding function overloads
Two
declare corresponding overloads if both declare functions satisfying all following conditions:
They have the same
, omitting the types of
(since C++23).
If both of them are non-static member functions, they need to additionally satisfy one of the following requirements:
Exactly one of them is an
implicit object member function
without ref-qualifier and the types of their object parameters, after removing top-level references, are the same.
(since C++23)Their object parameters have the same type.
Corresponding function template overloads
Two
function template declarations
declare corresponding overloads if both declare function templates satisfying all following conditions:
Their template parameter lists have the same length.
Their corresponding template parameters are
.
They have equivalent
, omitting the types of
(since C++23).
They have equivalent return types.
Their corresponding template parameters are either both declared without
, or both declared with equivalent constraints.
They have equivalent trailing
(if any).
(since C++20)If both are non-static members function templates, they need to additionally satisfy one of the following requirements:
Exactly one of them is an
implicit object member function
template without ref-qualifier and the types of their object parameters, after removing all references, are equivalent.
(since C++23)Their object parameters have equivalent types.
structA{friendvoidc();// #1};structB{friendvoidc(){}// corresponds to, and defines, #1};typedefintInt;enumE:int{a};voidf(int);// #2voidf(Int){}// defines #2voidf(E){}// OK, another overloadstructX{staticvoidf();voidf()const;// error: redeclarationvoidg();voidg()const;// OKvoidg()&;// error: redeclarationvoidh(thisX&,int);voidh(int)&&;// OK, another overloadvoidj(thisconstX&);voidj()const&;// error: redeclarationvoidk();voidk(thisX&);// error: redeclaration};Multiple declarations of the same entity
Unless otherwise specified, two declarations of entities declare the same entity if all following conditions are satisfied, considering declarations of unnamed types to introduce their
and
for linkage purposes (if any exists):
They correspond.
They have the same
, which is not a
or a
.
Neither is a name-independent declaration.
(since C++26)One of the following conditions is satisfied:
They appear in the same translation unit.
They both declare names with
.
A declaration of an entity or typedef name X is a redeclaration of X if another declaration of X is reachable from it; otherwise, it is a first declaration of X.
Restrictions
If any two declarations of an entity E violate the corresponding restriction below, the program is ill-formed:
If one declares E to be a variable, the other must also declare E as a variable of the same type.
If one declares E to be a
, the other must also declare E as a function of the same type.
If one declares E to be an
, the other must also declare E as an enumerator.
If one declares E to be a
, the other must also declare E as a namespace.
If one declares E to be a
, the other must also declare E as a class type
.
If one declares E to be an
, the other must also declare E as an enumeration type.
If one declares E to be a
, the other must also declare E as a class template
with an equivalent template parameter list (see
).
If one declares E to be a
, the other must also declare E as a function template with an equivalent template parameter list and type.
If one declares E to be an
, the other must also declare E as an alias template with an equivalent template parameter list and type-id.
(since C++11)If one declares E to be a (partial specialization of a)
, the other must also declare E as a (partial specialization of a) variable template with an equivalent template parameter list and type.
(since C++14)If one declares E to be a
, the other must also declare E as a concept.
(since C++20)Types are compared after all adjustments of types (during which
are replaced by their definitions). Declarations for an array object can specify array types that differ by the presence or absence of a major array bound. No diagnostic is required if neither declaration is reachable from the other.
voidg();// #1voidg(int);// OK, different entity from #1 (they do not correspond)intg();// Error: same entity as #1 with different typevoidh();// #2namespaceh{}// Error: same entity as #2, but not a functionIf a declaration H that declares a name with
precedes a declaration D in another translation unit U and would declare the same entity as D if it appeared in U, the program is ill-formed.
Potentially-conflicting declarations
Two declarations potentially conflict if they correspond but declare different entities.
If, in any scope, a name is bound to two declarations A and B that potentially conflict, B is not name-independent(since C++26), and A precedes B, the program is ill-formed:
voidf(){intx,y;voidx();// Error: different entity for xinty;// Error: redefinition}enum{f};// Error: different entity for ::fnamespaceA{}namespaceB=A;namespaceB=A;// OK, no effectnamespaceB=B;// OK, no effectnamespaceA=B;// OK, no effectnamespaceB{}// Error: different entity for Bvoidg(){int_;_=0;// OKint_;// OK since C++26, name-independent declaration_=0;// Error: two non-function declarations in the lookup set}voidh(){int_;// #1_++;// OKstaticint_;// Error: conflicts with #1 because// static variables are not name-independent}Notes
Feature-test macro ValueStdFeature
(C++26)
A nice placeholder with no name
Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR Applied to Behavior as published Correct behavior
(
) C++98 it was unclear whether an unnamed class or enumeration can
be redeclared if it has a typedef name for linkage purposes it can be redeclared
(
) C++98 it was unclear whether an unnamed enumeration can be
redeclared if it has an enumerator as a name for linkage purposes it can be redeclared
(
) C++98 the restrictions applied to multiple
declarations of the same entity were unclear made clear