不明确的引用和命名空间(来自两个外部库的定义冲突)

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

本文关键字:外部 两个 冲突 定义 引用 命名空间 不明确      更新时间:2023-10-16

我经历了我无法理解的定义崩溃。

示意性地问题如下:

主项目文件有两个包含:

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

第一个标头包括库中的其他几个标头,其中一个标头有一个直接(未被命名空间覆盖(定义:

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。

我在主程序中的任何地方都没有写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> ...

没有前面命名空间的::表示全局命名空间。

另一种方法是在lib2.h中没有using namespace lib3;,并正确限定lib3命名空间的内容。