7

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

问题的示意图如下:

主项目文件有两个包括:

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。

4

1 回答 1

11

我在主程序中没有写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) 行将其带入 namespace lib2,它现在在第 (4) 行也可见。

您可以通过完全限定类型来解决此问题:

::SparseMatrix<double> ...

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

另一种选择是不包含using namespace lib3;lib2.h正确限定lib3名称空间的内容。

于 2013-03-26T14:27:31.727 回答