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

时间:2012-11-07 16:05:57

标签: 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;
}

我用GCC 4.4编译。为什么它甚至让我编译这个?难道不存在我无法将const引用分配给非const引用的错误吗?

4 个答案:

答案 0 :(得分:13)

问题是,如果T类型为int&,则类型const T不是const int&,而是int & const。在模板替换和typedef结果中忽略引用上的非法顶级const。

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

答案 1 :(得分:5)

当TypeBufferFront为int&时,const TBufferTypeFront等同于int& const,其中const在模板替换期间被忽略,因为所有引用都是常量,即使它们所引用的不是。

因此,在使用int&进行实例化时,您的构造函数实际上是FrontBackBuffer(int&, int&),它可以按照给定的方式工作。

这是为什么许多人会使用T const代替const T的原因,以便更清楚地了解替换的发生方式,并允许他们从右到左阅读cv限定符

答案 2 :(得分: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)
  {
  };

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

现在这并不完美。这可以防止FrontBackBuffer的临时参数被移动,并通过引用而不是按值传递甚至小的便宜到复制类型(如char)。有标准的C ++ 0x技术可以做到这一点,如果你愿意的话,写起来有点尴尬。

答案 3 :(得分:0)

FrontBackBuffer::m_Front的类型为TBufferTypeFront,在您的模板实例化中会转换为int&。分配给int&时没有错。