我经历了我无法理解的定义的崩溃。
问题的示意图如下:
主项目文件有两个包含:
include <lib1.h>
include <lib2.h>
第一个 header 包括库中的其他几个 header ,其中一个 header 有一个直接的(未覆盖 namespace )定义:
template<typename T> class SparseMatrix;
lib2.h里面有如下内容
namespace lib2
{
using namespace lib3;
class ...
{
...
SparseMatrix<double> ...
...
}
}
在lib3里面,覆盖着命名空间,还有一个SparseMatrix类的定义。
每个库单独编译没有问题。当我尝试编译使用 的可执行文件时,编译器产生错误:
lib2.h:70:7: error: reference to 'SparseMatrix' is ambiguous
这对我来说很奇怪,因为我在主程序的任何地方都没有写
using namespace lib3;
因此,我认为这些定义没有理由崩溃。 我将不胜感激任何可能的问题解释。
当然,我可以将 lib1 中的定义包含在它们自己的命名空间中,但那样我就需要在那里修改相当多的文件,我宁愿不这样做。
评论: 下面的答案是正确的,但我也能够通过更改包含文件的顺序来解决这个问题,即首先包含 lib2,然后是 lib1。
最佳答案
nowhere in the main program do i write
using namespace lib3;
但是如果你查看 lib2.h
,正是这样写的。 lib3
的内容命名空间已被引入 lib2
并且现在在定义 SparseMatrix<double>
时可见对象。
可以想到lib2.h
在所有包含已解决之后就像这样:
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)
}
}
标有 (1) 的行声明了 SparseMatrix
这在第 (4) 行立即可见。第 (2) 行的声明不会是,但由于第 (3) 行将其带入命名空间 lib2
,它现在在第 (4) 行也可见。
你可以简单地通过完全限定类型来解决这个问题:
::SparseMatrix<double> ...
::
前面没有命名空间的表示全局命名空间。
另一种选择是没有 using namespace lib3;
在 lib2.h
并适当限定 lib3
的内容命名空间。
关于c++ - 不明确的引用和命名空间(来自两个外部库的定义冲突),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15639519/