1

最初に私のコードのレイアウト:

ああ

class STORAGE_CLASS_DECLARATOR A : public PureVirtual
{
   some member functions, all working;
   void someFunctionCallingOperator<<();
   friend std::ostream& operator << (std::ostream &, A *);
}

A.cpp

std::ostream& operator << (std::ostream & out, A * a){...}
void A::someFunctionCallingOperator<<(){...}

ここで、Storage_xxx_declarators は declspec のマクロです。宣言子の有無にかかわらず、フレンド関数を試してみましたが、役に立ちませんでした。

operator<< 関数で未解決の外部シンボルを取得します。

私の理解では、これは次のいずれかが原因である可能性があります。

  1. 関数の本体はありません。これは、ファイルが動作している他の関数に対して確実に解析されるため、明らかに真実ではありません。
  2. シンボルが正しくエクスポートされていません。繰り返しますが、私はこれがどのように起こっているのか途方に暮れており、実際のシナリオでは、ここで A の operator<< は実際に別のクラス B の operator<< を呼び出し、その関数にも同じエラーが表示されます。したがって、A の定義はある時点で解析されている必要があります。

リンクは別の段階であり、非常に単純なことを間違って行っているに違いないことを認識していますが、しばらく見つめていて、なぜこれが起こっているのかを理論的に推論できないので、SOに助けを求めています

ありがとう、AK

4

3 に答える 3

3

あなたのコメントに基づいて、あなたの設定は次のようなものだと思います:

ああ

namespace NN {

class STORAGE_CLASS_DECLARATOR A : public PureVirtual
{
   some member functions, all working;
   void someFunctionCallingOperator<<();
   friend std::ostream& operator << (std::ostream &, A *);
}

}

A.cpp:

using namespace NN;

std::ostream& operator << (std::ostream & out, A * a){...}
void A::someFunctionCallingOperator<<(){...}

これは非常に一般的なセットアップですが、現在のタイプの問題につながるため、使用しないことをお勧めします。で何が起こっているか見てみましょうA.cpp:

の定義を解析するとき、グローバル名前空間にはA::someFunctionCallingOperator存在しないため、 -ed 名前空間が考慮され、 に解決されます。AusingANN::A

ただし、の定義を解析するとoperator<<、演算子を namespace に配置する必要があることを示すものはまったくありませんNN。したがって、これはグローバル名前空間で喜んoperator<<定義されます。あとでinsideを使うと、( で宣言されている) が引数依存のルックアップで見つかったので、それを使います。結局、リンカーは、それが定義されていないことを正当に不平を言っています。NN::operator<<A.h<<someFunctionCallingOperatorNN::operator<<A.h

これを解決する正しい方法は、ヘッダー ファイルで行うのと同じように、名前空間の内容を停止using namespace NNして適切に囲むことです。A.cpp

namespace NN {

std::ostream& operator << (std::ostream & out, A * a){...}
void A::someFunctionCallingOperator<<(){...}

}
于 2013-03-15T13:40:07.763 に答える
1

簡単な答え:演算子の戻り値のタイプとパラメーターの両方が、定義と実装全体で同一であることを確認してください。

少し長い答え:

オペレーターの戻りタイプを省略したようです。フレンド関数の定義にはマクロが含まれていますが、実装はの戻り型を識別しostream&ます。マクロにが含まれていない場合、ostream&未解決の外部シンボルエラーが発生する可能性があります。

また、実装でパラメーターを省略しました。これにより、パラメーターで演算子を使用しようとすると、未解決の外部シンボルエラーが発生します(の場合は通常どおり<<)。コンパイラーは<<、単一のパラメーター(および戻り型)を使用したの実装を探しますが、空のパラメーター・リストを使用したostream&の実装のみを検索します。operator<<

于 2013-03-15T11:08:53.567 に答える