问题
I have two source files, a.cpp
and b.cpp
. In a.cpp
, I have a function, foo
:
namespace ns { void foo() { std::cout << "foo!"; } }
In b.cpp
, I have another function in namespace ns
in which I'd like to prototype and call foo
:
namespace ns
{
void bar()
{
void foo();
foo();
}
}
While the above is syntactically valid, it leads the compiler to think that foo
is in the global namespace (or at least that's what I've deduced from the linker errors I get when I do this). My first two ideas to fix that were void ns::foo();
and namespace ns { void foo(); }
, but neither is valid. Is it possible to correctly prototype this function inside bar
?
Note that I know I could simply move this to the file scope or a header file, there have been many questions asked about this, but I want to specifically prototype it inside another function. My compiler is MSVC 14.0 with the latest update.
EDIT: Based on some tests I've done and our discussion in the comments, I believe this is an MSVC bug. Compare:
namespace ns
{
void bar()
{
void foo(); // link error, MSVC assumes global namespace
foo();
}
void foo() { }
} // namespace ns
This fails, as stated previously. However, moving the prototype out of the function makes MSVC correctly place the prototyped function in the enclosing namespace:
namespace ns
{
void foo(); // all fine
void bar()
{
foo();
}
void foo() { }
} // namespace ns
回答1:
The standard is clear about this point:
3.3.2/11: (..) Function declarations at block scope and variable declarations with the extern specifier at block scope refer to declarations that are members of an enclosing namespace (...)
Consequently:
void bar()
{
void foo(); // should refer to ns::foo() according to 3.3.2/11
foo();
}
and the linking should refer to the separately compiled function which has the same signature:
1.3.17 signature:
<function>
name, parameter type list , and enclosing namespace (if any) [Note: Signatures are used as a basis for name mangling and linking.—end note ]
来源:https://stackoverflow.com/questions/34559689/forward-declaring-a-function-in-a-namespace-inside-another-function-in-that-name