【问题标题】:Ambiguous reference and namespace (clash of definitions from the two external libraries)不明确的引用和命名空间(来自两个外部库的定义冲突)
【发布时间】:2013-03-26 14:24:48
【问题描述】:

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

问题大致如下:

主项目文件有两个包含:

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。

【问题讨论】:

    标签: c++ oop shared-libraries static-libraries


    【解决方案1】:

    我在主程序中没有写using namespace lib3;

    但是,如果您查看lib2.h,确实已经写了。 lib3 命名空间的内容已被引入 lib2,现在在定义 SparseMatrix&lt;double&gt; 对象时可见。

    您可以将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 命名空间的内容。

    【讨论】:

    • 好吧,但是这包含在它自己的命名空间“命名空间 lib2”中,这不是有帮助吗?我实际上虽然这个“使用命名空间 lib3”只在 lib2 中相关,而不是在稍后将包含它的库之外。
    • @Denis 但是包含SparseMatrix&lt;double&gt; 的类在lib2 命名空间内。所以它当然会受到using namespace lib3 的影响,它也在lib2 内部。
    • 但是你在 lib2 命名空间中引用了SparseMatrix,所以你可能想要lib2::SparseMatrix::SparseMatrix。两者都可以通过写SparseMatrix 来引用。因此:: 说“我想要全局”。
    • @sftrabbit 对不起,我一定是误解了一些东西,但我在主程序中没有“使用命名空间 lib2”。所以它应该留在它的命名空间内,我像 lib2::ObjectFoo... 一样使用它。
    • @Denis 看看我的编辑。我已经对代码进行了注释并描述了为什么类中有两个可见的SparseMatrix 定义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 2012-01-02
    • 1970-01-01
    • 1970-01-01
    • 2012-05-07
    • 2017-10-05
    • 2015-10-23
    相关资源
    最近更新 更多