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

Gab*_*iel 1 c++ templates reference

怎么可能在这里调用模板类

FrontBackBuffer,模板参数为TBackBufferType,TFrontBufferType

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

};
Run Code Online (Sandbox Code Playgroud)

我想实现以下目标:

  • 为了在代码中保持一致,我会优先考虑,无论缓冲区内的Type是什么,都要有一个函数getFront/Back,它应该总是返回一个对缓冲区的引用(const或非const,取决于type:例如const int = T应该返回一个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* ....
    
    Run Code Online (Sandbox Code Playgroud)

我想这样,因为我想避免更改语法,如果我将缓冲区类型从引用更改为指针(我需要取消引用)

  • 这样的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* ....
Run Code Online (Sandbox Code Playgroud)

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

Pio*_*ycz 5

您需要专门化(特征技术)模板的一部分,如下所示:

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

更新
请注意返回引用的特殊函数 - 如果要对指针执行不同的操作,则需要它 - 返回它的引用.
结束更新

并为引用和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;
        }
    };
Run Code Online (Sandbox Code Playgroud)

更新
和指针的这种"特殊"特化 - 所以它们将作为参考:

//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;
        }
    };
Run Code Online (Sandbox Code Playgroud)

((但我不确定这个指针的专业化是一个很好的设计......))


结束更新

并在您的类模板中使用:

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

};
Run Code Online (Sandbox Code Playgroud)

它按预期工作:http: //ideone.com/e7xfoN