1

ここでテンプレート化されたクラスを呼び出すにはどうすればよいですか

テンプレート パラメーターTBackBufferType、TFrontBufferTypeを持つ FrontBackBuffer

template< typename TBufferTypeFront, typename TBufferTypeBack = TBufferTypeFront>
class FrontBackBuffer{
  public:
  explicit FrontBackBuffer(
     TBufferTypeFront const & m_front,
     TBufferTypeBack  const & m_back):
     m_Front(m_front),
     m_Back(m_back)
  {
  };

  ~FrontBackBuffer()
  {};

  typename std::remove_reference<
    typename std::remove_pointer<TBufferTypeFront>::type
  >::type  & getFront(){return m_Front;}    // error: invalid initialization of reference of type 'A&' from expression of type 'A*'| (here T is A)


  typename std::remove_reference<
    typename std::remove_pointer<TBufferTypeBack>::type 
  >::type  & getBack(){return m_Back;}

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

};

私は次のことを達成したいと思います:

  • コード内で一貫性を保つために、バッファー内の Type が何であれ、常にバッファーへの参照を返す関数getFront/Backを使用することをお勧めします (const または non-const のいずれかによって異なります)。 type: eg const int = T should return a const int & reference! このようなコードを書きたいと思います

    FrontBuffer<const int&, std::vector<int> > a;
    a.getFront() = 4 //COmpile error! OK!;
    a.getBack()[0] = 4;
    FrontBuffer< int*, GAGAType * > b;
    b.getBack() = GAGAType();
    b.getFront() = int(4);  // this is no ERROR, i would like to get the reference of the memory location pointet by int* ....
    

バッファーの型を参照からポインター (逆参照する必要がある場所) に変更した場合に構文の変更を避けたいので、これが必要です。

  • このような Buffer クラスは、可能なすべてのタイプ (shared_ptr など) で受け入れることができますか? asd

  • 私が欲しいのはアクセスだけで、非常にパフォーマンスが高く、コピーなどはありません。

  • この汎用バッファの書き方が本当にわかりませんか? 誰かが手がかりを持っていますか?

ありがとう!!!

EDIT1逆参照されたポインターに割り当てることもできるようにしたい:

b.getFront() = int(4);  // this is no ERROR, i would like to get the reference of the memory location pointet by int* ....

それが私の特性に関する問題の出番です!

4

1 に答える 1

5

次のように、テンプレートの一部を特殊化する (特性テクニック)必要があります。

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

更新
参照を返すための特別な関数に注意してください-ポインターに対して異なる動作をさせたい場合に必要です-それに対する参照を返します。
更新終了

そして、参照と const 参照を特殊化します。

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;
        }
    };

((ただし、このポインターの特殊化が適切な設計であるかどうかはわかりません...))


更新終了

クラステンプレート内での使用法:

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


   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 m_front,
     TBufferTypeBackCon m_back):
     m_Front(m_front),
     m_Back(m_back)
  {
  };

  ~FrontBackBuffer()
  {};
  // See here special functions from traits are used:
  TBufferTypeFrontRef getFront(){return MyRefTypes<TBufferTypeFront>::getRef(m_Front); }    
  TBufferTypeBackRef getBack(){return MyRefTypes<TBufferTypeBack>::getRef(m_Back); }

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

};

期待どおりに動作します: http://ideone.com/e7xfoN

于 2012-11-08T15:50:29.570 に答える