7

私は理解できない定義の崩壊を経験します。

概略的に問題は次のとおりです。

メインプロジェクトファイルには2つのインクルードがあります。

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

最初のヘッダーには、ライブラリからの他のヘッダーがいくつか含まれています。そのうちの1つには、直接(名前空間でカバーされていない)定義があります。

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)
    }
}

SparseMatrix(1)とマークされた行は、行(4)にすぐに表示されることを宣言します。行(2)の宣言はそうではありませんが、行(3)はそれを名前空間lib2に持ってくるので、行(4)にも表示されます。

タイプを完全に修飾するだけで、これを回避できます。

::SparseMatrix<double> ...

::先行する名前空間がない場合は、グローバル名前空間を示します。

もう1つの方法は、名前空間の内容を含まずusing namespace lib3;lib2.h適切に修飾することです。lib3

于 2013-03-26T14:27:31.727 に答える