外部 C API を中心にヘッダーのみの C++ ライブラリを作成しようとしています。C API はvoid *
ポインタをハンドルとして使用します。アイデアは次のとおりです。
// resource.hpp
class Resource {
public:
// RAII constructor, destructor, etc.
// ...
void do_something(const Handle & h) {
do_something_impl( (void *) h);
}
};
// handle.hpp
class Handle
{
public:
Handle(size_t n, const Resource & res)
: p_(res.allocate(n)), res_(res) {}
// cast operation
operator void *() const { return p_; }
private:
void * p_;
Resource & res_;
};
ここでの問題は、(a) ハンドルがリソースへの参照を保持する必要があり、(b) リソースがハンドルを void * にキャストできる必要があることです。残念ながら、これは循環依存につながります。
これを再構築する方法についてのアイデアはありますか?
注: 答えは、単純に「xxx.hpp をインクルード」したり、クラスの 1 つを前方宣言したりすることではありません。これはどうにかして再構築する必要がありますが、どうすればよいかわかりません。
リソース ファイルの先頭に前方宣言として aを追加しclass Handle
ても機能しません。これは、(void *)
キャストがハンドル定義の一部であり、リソースがまだ認識できないためです。同様に、キャストをvoid * ptr()
メンバー関数に変更すると、同じ問題が発生します。
関数定義を .cpp ファイルに移動することも答えではありません。ヘッダーのみにする必要があります。