1

最近、ORM反射にブーストミラーを使用し始めたので、DB関連のボイラープレートコードの量を最小限に抑えることができます。

私が遭遇したパターンの1つを以下に示します。

Barのコードは、でも同じように見えるので、Baz疑問に思っていましたが、このコードをさらに折りたたむことは可能ですか?

インターフェイスが同じように見えるといいのですgetValues()が、代わりに同じ実装を使用することもできFooます。

#include <iostream>

template< typename T >
struct Foo
{
    static std::ostream& GetValues_Worker( std::ostream& os, T const& t )
    {
        // do boost mirror reflection stuff here
        return os;
    }
};

struct Bar : 
    public Foo<Bar>
{
    // REFACTOR IF POSSIBLE:  this code will always look the same - even for Baz
    std::ostream& 
    getValues( std::ostream& os ) const
    {
        return GetValues_Worker( os, *this );
    }
};

struct Baz : 
    public Foo<Baz>
{
    // REFACTOR IF POSSIBLE:  looks the same as Bar
    std::ostream& 
    getValues( std::ostream& os ) const
    {
        return GetValues_Worker( os, *this );
    }
};

int main( int argc, char* argv[] )
{
    Bar b;
    std::cerr << b.getValues( std::cerr ) << std::endl;
}

答え

以下のecatmurの答えはほとんどの場合うまくいくことがわかります。私の特定の状況では、彼のソリューションを実際のコードに適合させました。4つのケースのうち2つで機能しました。それが機能しなかった2つのケースでは、上記のミッキーマウスの例の範囲を少し超えていました。私が得ていたコンパイル時エラーを説明するSOで見つけた最も近い説明は、おそらくこの投稿です。問題の核心は、私のワーカーコード内で起こっていたことに関連しているように見えました。失敗した2つのケースでは、ブーストミラーの実行時リフレクションの結果から取得した内容に基づいて、サブクラスのメンバーの出力ストリーミングを実行していました。これは推論できない文脈の場合であることが判明したと思います。これらの2つの失敗したケースの解決策が正確に機能する理由はまだわかりません(仮想メソッドの形式でビジターを使用すると問題が回避される理由)。とにかく、私はそのアプローチに出くわし、コードをもう少し削減しようとしましたが(これらの4つのケースでは)、そのうちの2つでは、推論できないコンテキストの問題に遭遇することなく、そのコードをこれ以上削減できませんでした。

4

1 に答える 1

4

Bar::getValuesFoo<Bar>CRTPダウンキャストを使用するように移動できます。

template< typename T >
struct Foo
{
    static std::ostream& GetValues_Worker( std::ostream& os, T const& t )
    {
        // do boost mirror reflection stuff here
        return os;
    }

    std::ostream& getValues( std::ostream& os ) const
    {
        return GetValues_Worker( os, *static_cast<T const *>(this) );
    }
};

この時点で、次の2つの方法を組み合わせた方がよいでしょう。

template< typename T >
struct Foo
{
    std::ostream& getValues( std::ostream& os ) const
    {
        T const &t = *static_cast<T const *>(this);
        // do boost mirror reflection stuff here
        return os;
    }
};
于 2012-12-18T13:44:27.517 に答える