Can namespace functions be declared at block scope outside the namespace they were defined at?
This code does not compile when DECLARED_IN_NS
is defined as 1
:
#define DECLARED_IN_NS 1 // can be either 0 or 1
#if DECLARED_IN_NS == 1
namespace ns
{
#endif
void
func1()
{
}
void
func2()
{
}
#if DECLARED_IN_NS == 1
} // namepace ns
#endif
int main( )
{
#if DECLARED_IN_NS == 1
void ns::func1(); // compile error
void ns::func2(); // compile error
ns::func1();
ns::func2();
#elif DECLARED_IN_NS == 0
void func1();
void func2();
func1();
func2();
#endif
}
It shows some errors:
error: qualified-id in declaration before '(' token
28 | void ns::func1();
| ^
The code compiles when func1
and func2
are defined at global namespace. However, it doesn't compile when they are defined inside a namespace (e.g. ns
).
Is there a way to fix this?
CodePudding user response:
I can't find a definitive reference to this in the standard, but I don't think there'd be much point to allow it intentionally.
Even if it could appear at block scope, it'd be pointless. A declaration that uses a nested name specifier cannot be the first declaration for an entity.
[dcl.meaning.general]
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 (or, in the case of a namespace, of an element of the inline namespace set of that namespace ([namespace.def])) ...
This makes this code like this valid
namespace ns
{
void func();
} // namepace ns
void ns::func(); // repeated declaration - optional
void ns::func() { // definition
}
Now, returning to the block scope case, you'd need a namespace scoped declaration preceding it anyway, so the whole exercise is moot.
Furthermore, the behavior of declaring functions in block scope has aspects that are aptly named by the c community, but it remains due to C compatibility. It would certainly not be beneficial to allow it for nested names intentionally.