0

私は今朝この問題に遭遇しました:

次のように使用できるジェネリッククラスFrontBackBufferを作成したいと思います(いくつかの例)。

編集いくつかの紛らわしい部分を削除しました!

int bb=10;
int fb=3;
FrontBackBuffer< const int*, int & > buf(&fb, &bb);
buf.getBack() = 4; // change from 10 to 4
// buf.getFront() = 5; NO! is const!

buf.swap();
//NOW getFront() and getBack() should return  4 and 3!

FrontBackBuffer< int, const & int > buf(14, bb);
buf.getBack() = 5; // change from 4 to 5
// buf.getFront() = 5; NO! is const!

buf.swap();   
//NOW getFront() and getBack() should return  5 and 14!

2つのバッファを格納し、同じ基になるタイプである必要があります(static_assertを参照)。これらのバッファーは、ポインター型または参照型であり、constまたはnonconstでもかまいません。2つの機能getFront()getBack()。これらの関数は常に、constまたはnon-constのいずれかの基になるバッファへの参照を返します。だからこそ、あらゆる種類のMyRefTypes形質の特殊化があります。

これまでに機能するクラスは次のとおりです。

template< typename TBufferTypeFront, typename TBufferTypeBack = TBufferTypeFront>
class FrontBackBuffer {

// If <const * int , int&> --> this result in is_same< int , int > 
// STATIC_ASSERT( std::is_same< RemoveModifiers<TBufferTypeFront>::type, typename RemoveModifiers<TBufferTypeFront>::type>::result )

public:

    template <typename T>
    struct MyRefTypes {
        typedef const T & Con;
        typedef T& Ref;
        typedef const T& CRef;
        static Ref getRef(T& v) {
            return v;
        }
    };

//Specialization for Reference
    template <typename T>
    struct MyRefTypes<T&> {
        typedef T & Con;
        typedef T& Ref;
        typedef const T& CRef;
        static inline Ref getRef(T& v) {
            return v;
        }
    };

//Specialization for const Reference
    template <typename T>
    struct MyRefTypes<const T&> {
        typedef const T & Con;
        typedef const T& Ref;
        typedef const T& CRef;
        static inline Ref getRef(const T& v) {
            return v;
        }
    };

//Specialization for const
    template <typename T>
    struct MyRefTypes<const T> {
        typedef const T & Con;
        typedef const T& Ref;
        typedef const T& CRef;
        static inline Ref getRef(const T& v) {
            return v;
        }
    };

//Specialization for pointers
    template <typename T>
    struct MyRefTypes<T*> {
        typedef T* Con;
        typedef T& Ref;
        typedef T* const CRef;  //! note this is a pointer....
        static inline Ref getRef(T* v) {
            return *v;
        }
    };

//Specialization for const pointers
    template <typename T>
    struct MyRefTypes<const T*> {
        typedef const T* Con;
        typedef const T& Ref;
        typedef const T* const CRef; //! note this is a pointer....
        static inline Ref getRef(const T* v) {
            return *v;
        }
    };


    typedef typename MyRefTypes<TBufferTypeFront>::Ref TBufferTypeFrontRef;
    typedef typename MyRefTypes<TBufferTypeFront>::CRef TBufferTypeFrontCRef;
    typedef typename MyRefTypes<TBufferTypeFront>::Con TBufferTypeFrontCon;

    typedef typename MyRefTypes<TBufferTypeBack >::Ref TBufferTypeBackRef;
    typedef typename MyRefTypes<TBufferTypeBack >::CRef TBufferTypeBackCRef;
    typedef typename MyRefTypes<TBufferTypeBack >::Con TBufferTypeBackCon;

    explicit FrontBackBuffer(
        TBufferTypeFrontCon  front,
        TBufferTypeBackCon   back):
        m_Front(front),
        m_Back(back)
    {
             m_pBack = (void*)&m_Back;
             m_pFront = (void*)&m_Front;

    };


    ~FrontBackBuffer()
    {};

    TBufferTypeFrontRef getFront() {
        return MyRefTypes<TBufferTypeFront>::getRef(m_Front);
    }
    TBufferTypeBackRef getBack() {
        return MyRefTypes<TBufferTypeBack>::getRef(m_Back);
    }
    private:

    void swap(){
         void * temp = m_pFront;
         m_pFront = m_pBack;
         m_pBack = temp;
    }

    TBufferTypeFront * m_pFront;       ///< The pointer to front buffer
    TBufferTypeBack * m_pBack;         ///< The pointer to back buffer

    TBufferTypeFront m_Front;       ///< The front buffer
    TBufferTypeBack m_Back;         ///< The back buffer

};

問題は今です(私は完全に正しく解決することはできません):バッファを交換するジェネリック関数を追加するにはどうすればよいですか?swap()コピーは作成しないでください。私は2つのポインターについて考えvoid * m_pFrontvoid *m_pBackそれらを使用してジョブを実行し、正しく割り当てました(コンストラクターを参照)。

しかし、これらのゲッター関数をどのように書くのかは私には謎です。

    TBufferTypeFrontRef getFront() {
        return MyRefTypes<TBufferTypeFront>::getRef(m_Front);
    }
    TBufferTypeBackRef getBack() {
        return MyRefTypes<TBufferTypeBack>::getRef(m_Back);
    }

一日の終わりにそれはうまくいくはずです:-)助けてくれてありがとうそしてこのパズルを解こうとしている:-)!

4

2 に答える 2

0

あなたが説明したタスクを達成するために投稿したすべてのコードが必要な理由がよくわからないことを認めなければなりませんが、何かが欠けている可能性があります. ただし、同じタイプの2つのバッファを一般的だが効率的な方法で交換したいだけだと考えると、次のことをお勧めします。

template<typename BufferType>
class FrontBackBuffer
{
private:
    BufferType buffers[2];
    int _back,_front;
public:
/*
omitting copy constructors, operators etc for brevity
*/
    FrontBackBuffer()
        : _front(0), _back(1)
    {
         /*
           You can also start with front and back pointing to the same memory it is of no  importance if you remember to swap them once or if you just set the back buffer and never the front
         */
    }
    BufferType & getFront()
    {
        return buffers[_front];
    }
    BufferType & getBack()
    {
        return buffers[_back];
    }
    void swap()
    {
        _front = _back;
        _back = (_front + 1) % 2;
    }
};

そして、次のように使用できます。

int intArray[] = {1,2,3,4};

FrontBackBuffer<int*> intPtrBuffers;
intPtrBuffers.getBack() = new int[4];
intPtrBuffers.getFront() = new int[4];

memcpy(intPtrBuffers.getBack(), intArray, sizeof(intArray));
intPtrBuffer.swap();
于 2012-11-10T17:32:56.217 に答える