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

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

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

问题的示意图如下:

主项目文件有两个包含:

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/

相关文章:

c++ - 如何从跟踪器响应中获取对等方的 IP 和端口

c# - 在 C# 中通过驱动类 B 对象访问基类 A 函数

shared-libraries - 是什么导致sprof提示“ld.so检测到不一致”?

c++ - 如何在 bleeding edge linux 上编译程序以在旧 linux 上运行

linux - 如何thread_local!在 rust 中使用动态库?

c++ - 预处理器字符串化宏不起作用

c++ - 为什么我会收到错误 "Floating point exception"?

c++ - 模板的一些问题

c++ - 从覆盖函数调用覆盖函数

c# - 继承中的方法调用