模板忽略了const(为什么?)

Gab*_*iel 7 c++ templates constructor const default-constructor

有人知道,为什么这个编译?

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

public:


  FrontBackBuffer(
    const TBufferTypeFront  front, 
    const TBufferTypeBack back):    ////const reference  assigned to reference???
     m_Front(front),
     m_Back(back)
  {
  };

  ~FrontBackBuffer()
  {};

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

};

int main(){
    int b;
    int a;
    FrontBackBuffer<int&,int&> buffer(a,b); //
    buffer.m_Back = 33;
    buffer.m_Front = 55;
}
Run Code Online (Sandbox Code Playgroud)

我用GCC 4.4编译.为什么它甚至让我编译这个?不应该有一个错误,我不能将const引用分配给非const引用吗?

Arm*_*yan 13

问题是如果类型Tint&,那么类型const T不是const int&,但是int & const.在模板替换和typedef结果中忽略引用上的非法顶级const.

如果,另一方面Tconst int,则T&const int&


Dav*_*e S 5

当TypeBufferFront是int&,const TBufferTypeFront就相当于int& const,其中const为模板替换期间被忽略,因为所有的引用是不变的,即使他们是指哪些不是.

因此,在实例化时int&,您的构造函数是有效的FrontBackBuffer(int&, int&),其作用与给定的一样.

这是一个为什么许多人会使用T const而不是const T更清楚地知道替换发生的原因的例子,以及允许他们从右到左阅读cv-qualifiers.


Yak*_*ont 2

为了让代码做你想做的事情,它必须阅读:

  FrontBackBuffer(
    typename std::remove_reference<TBufferTypeFront>::type const&  m_front, 
    typename std::remove_reference<TBufferTypeBack>::type const& m_back):    ////const reference  assigned to reference???
    m_Front(m_front),
    m_Back(m_back)
  {
  };
Run Code Online (Sandbox Code Playgroud)

它具有添加的“功能”,当用于构造 时,它将其他类型转换为 const 引用FrontBackBuffer

现在这并不完美。这可以防止临时参数被移动,并通过引用而不是通过值传递FrontBackBuffer甚至很小的廉价复制类型(例如)。char有一些标准的 C++0x 技术可以做到这一点,如果您关心的话,编写这些技术会有点尴尬。