0

マトリックス管理のロジックをラップするクラスがあります。一方、行列操作操作 (LU 因数分解など) に費やす重要な時間の処理に特化した一連のメソッドがあります。

クラスは、そのファイルで定義された関数を使用します。そのファイルは、そのクラスの要素にアクセスできる必要があります。これらの特殊なメソッドを上記のクラスの友達にする必要があります。これにより、1 つのヘッダーを別のヘッダーに含めることができます。

私の問題

前に説明した状況は、ここで次のようにコーディングされます。最初のコードは を参照していmat.hppます。

#ifndef MAT_HPP
#define MAT_HPP
#include "operations.hpp"
namespace nsA {
template <typename T>
// Templated class because matrices can be real or complex
class mat {
   // Members...
   friend template <typename U> 
   void exec_lu(const mat<U>& in, const mat<U>& out);
   // Members...
} /* class end */
}
#endif
#endif

2つ目のファイルはoperations.hpp

#ifndef OPERATIONS_HPP
#define OPERATIONS_HPP
#include "mat.hpp"
namespace nsA {
namespace nsB {
template <typename T>
void exec_lu(const mat<T>& in, const mat<T>& out);
}
}
#endif

問題は、コンパイラが不平を言い始めることです。

ノート

mat.hppフレンド宣言をコメント化してインクルージョンを残すと、コンパイラーは「operations.hpp」で型matが定義されていないことを通知することを考慮してください!

インクルードもコメントし、mat.hppフレンド宣言もコメントしておくと、コンパイラは問題ありません!

これに取り組む方法は?

ありがとうございました

4

2 に答える 2

2

いくつかの前方宣言を追加するだけでこれを行うことができます...しかし、もう少しコードを追加することでさらにうまくいくことができます:

template <typename T> class mat;
template <typename T> void exec_lu( const mat<T>&, const mat<T>& );
template <typename T>
class mat {
   friend void exec_lu<T>( const mat<T>&, const mat<T>& );
};
template <typename T>
void exec_lu( const mat<T>& a, const mat<T>& b ) { ... }

このアプローチとあなたのアプローチの主な違い (構文の制限を修正する以外) は、このアプローチでは の単一のインスタンス化、特にアクセスがexec_lu必要インスタンス化にアクセスが許可されることです。あなたのコードでは (修正後)、 のすべての特殊化が の特殊化にアクセスできます(つまり、プライベート メンバーにアクセスできますが、 ...)、おそらくそれは望ましくありません。mat<T>exec_lumatexec_lu<int>mat<int>mat<double>

テンプレートのフレンドを宣言するためのさまざまなオプションの詳細については、関連する質問に対するこの回答をお読みください。

于 2012-06-29T03:30:07.187 に答える
1

これを機能させるには、クラスを前方宣言する必要があります。次のようになります。

ファイル mat.hpp:

#ifndef MAT_HPP
#define MAT_HPP
namespace nsA {
template <typename T>
class mat;
namespace nsB {
  template <typename T> 
  void exec_lu(const mat<T>& in, const mat<T>& out);
}
template <typename T>
class mat {
   friend void exec_lu(const mat<T>& in, const mat<T>& out);
};
}
#endif

そしてファイル operations.hpp:

#ifndef OPERATIONS_HPP
#define OPERATIONS_HPP
#include "mat.hpp"
namespace nsA { namespace nsB {
template <typename T>
void exec_lu(const mat<T>& in, const mat<T>& out);
}}
#endif

あなたの最初の宣言は、私のものよりも友好的です。私のものは、クラスのタイプ名に一致する関数にのみ友情を与えます。

于 2012-06-29T03:25:16.563 に答える