Ambiguous reference and namespace (collision of definitions from two external libraries)

I crash definitions that I cannot understand.

Schematically, the problem is as follows:

The main project file consists of two parts:

include <lib1.h> include <lib2.h> 

The first header includes a couple of other library headers, one of which has a direct (not covered by namespace):

 template<typename T> class SparseMatrix; 

In lib2.h is inside inside

 namespace lib2 { using namespace lib3; class ... { ... SparseMatrix<double> ... ... } } 

Inside lib3, covered by the namespace, there is also a definition for the SparseMatrix class.

Each library is separately compiled without problems. When I try to compile an executable file that the compiler uses, an error occurs:

 lib2.h:70:7: error: reference to 'SparseMatrix' is ambiguous 

Which looks strange to me, since nowhere in the main program do I write

 using namespace lib3; 

Thus, I see no reason why these definitions should be destroyed. I would really appreciate any possible explanation of the problem.

Of course, I can enclose the definitions from lib1 in my own namespace, but then I will need to modify quite a few files there, which I would prefer not to do.

COMMENT: the answer is below, but I was also able to work around the problem by changing the order of the included files, i.e. enable lib2 first and then lib1 first.

+4
source share
1 answer

nowhere in the main program do I write using namespace lib3;

But if you look in lib2.h , that is what was written. The contents of the lib3 namespace lib3 been migrated to lib2 and are now displayed when defining a SparseMatrix<double> object.

You can think of lib2.h as something like this, in the end, have been resolved:

 template <typename T> class SparseMatrix; // (1) namespace lib3 { template <typename T> class SparseMatrix; // (2) } namespace lib2 { using namespace lib3; // (3) class ... { ... SparseMatrix<double> ... // (4) // ::SparseMatrix<double> would only see (1) // lib2::SparseMatrix<double> would only see (2) } } 

The line marked (1) declares SparseMatrix , which immediately appears in line (4). The declaration in line (2) would not exist, but since line (3) transfers it to the lib2 namespace, it now also appears in line (4).

You can get around this simply by fully assigning the type:

 ::SparseMatrix<double> ... 

:: without a preceding namespace denotes a global namespace.

Another alternative is to not use using namespace lib3; in lib2.h and properly qualify the contents of the lib3 namespace.

+4
source

All Articles