I've found this odd case of some code (below) doesn't compile under Visual Studio 2008 and produces an "error C2872: 'Ambiguity' : ambiguous symbol" on line 12.
Removing the using namespace RequiredNamespace
on the last line fixes the error, but I'd expect that putting using namespace
at the end of a file should have no effect. It also relies on AnotherFunction
being a template function, so I expect the compiler is generating the templated functions in the wrong scope, or isn't resetting the list of namespaces being used before doing so.
The same code compiles under GCC.
Both compilers seem to generate the code for TemplatedFunction
after the using namespace Namespace
definition, at least as far as I can tell by introducing errors and looking at the order they're output.
namespace Ambiguity
{
class cSomeClass
{
};
template<class T>
void TemplatedFunction(T a)
{
// this is where the error occurs, the compiler thinks Ambiguity
// might refer to the class in RequiredNamespace below
Ambiguity::cSomeClass();
}
}
namespace RequiredNamespace
{
// without a namespace around this class, the Ambiguity class
// and namespace collide
class Ambiguity
{
};
}
int main()
{
// to force the templated function to be generated
Ambiguity::TemplatedFunction(4);
}
// removing this removes the error, but it shouldn't really do anything
using namespace RequiredNamespace;
Obviously this is a manufactured example, but the original is extracted from a real case where the using namespace
is in a auto-generated file produced by 3rd party code.
Is this a bug in the compiler?
I agree that it is a bug, but some insight into what is going on can be obtianed by generating the assembly listing corresponding to your file (use the /Fa option of cl.exe).
So, comment out the using declaration, generate the .asm file and open it in a text editor. Scan the file and you can see that the instantiation of the template is at the bottom of the file (it starts with ??$TemplatedFunction@H@Ambiguity@@YAXH@Z PROC
), and it is under the assembly generated for the main function (starts with _main PROC
). The error message said "see reference to function template instantiation", so it is referring to the instantiation of the template function, and the assembly listing makes clear this instantiation is at the bottom of the file.
Now, edit the code to replace the template function with NonTemplatedFunction(int a)
and compile, generating an assembly listing. View the assembly listing and you will see the assembly code generated for NonTemplatedFunction(int a)
appears above _main PROC
.
What does all this babble mean? When the Visual Studio 2008 compiler turns your templates into actual code, it is effectively appending some code to the end of your file after your using declaration. Your using declaration means the names in the automatically generated code are "ambiguous". The process gcc uses to instantiate templates obviously avoids this problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With