带get函数的模板类总是返回引用,

时间:2012-11-08 15:42:21

标签: c++ templates reference

如何在这里设置一个名为

的模板类 带有模板参数 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或非const取决于类型:例如const int = T应该返回一个const int&amp; 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* ....

这就是我的特质问题所在!

1 个答案:

答案 0 :(得分:5)

您需要专门设置(traits technique)模板的一部分,如下所示:

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