4

私はおそらく、単純な問題であるべきものを解決するためにここに到達しています。ここでこの質問を開始しました: コンパイル時に基本クラスの型を取得する

基本的に、クラスに独自のポインター型を管理させようとしています。一部の構造には参照カウントが組み込まれており、他の構造には組み込まれていない C ライブラリをラップしています。そうでないものは、shared_ptr を使用したいと思います。そうであれば、intrusive_ptr を使用したいと思います。適切なラッパーを確実に使用するために、プログラマーの知性に頼ることは避けたいと思います。最終的には、この動作に依存する機能をさらに追加したいと考えていますが、まだできていません。

@Yakk は、テンプレート タイプのエイリアスを使用した興味深いソリューションを思いつきました。私はそれを実装しようとしました。残念ながら、循環参照をコンパイラが満足するように解決できない状況に陥っています。「using pointer=」行を指している「ネストされた名前指定子で指定された不完全な型 'Test2'」というエラーが表示されます。また、Test::f() の定義について、奇妙な「定義が戻り値の型の宣言と異なる」というメッセージが表示されますが、最初のエラーが解決されると、それ自体が解決されるのではないかと思います。

このエラー タイプで見つけた参照のほとんどは、ヘッダー ファイルの順序付けに関するものですが、すべてが 1 つのファイルに含まれている場合でも、この問題を解決するための順序付け方法がわかりません。

何か案は?

#include <iostream>
#include <memory>


template<typename T>
class Pointered: public std::enable_shared_from_this<T>
{
public:
    using pointer=std::shared_ptr<T>;     //<-- incomplete type named error
    using weakPointer = std::weak_ptr<T>;
};


template<typename T>
using Ptr =  typename T:: pointer;

template<typename T>
using WkPtr = typename T:: weakPointer;


class Test2;

class Test:public Pointered<Test>
{
public:
    Ptr<Test2> f();
};


class Test2:public Pointered<Test2>
{
public:
    Ptr<Test> p;
    Test2(Ptr<Test> ptr):p(ptr){}
};


int main(int argc, const char * argv[])
{
    Ptr<Test> p=std::make_shared<Test>();
    Ptr<Test> p3=p;
    p->f();
    std::cout << "Refcount: " << p.use_count() << std::endl;
}


//definition differs from declaration in return type error here
Ptr<Test2> Test::f()
{
    return Ptr<Test2>(new Test2((Ptr<Test>)shared_from_this()));
}
4

1 に答える 1