7

有人知道,为什么会编译?

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

4 回答 4

13

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

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

于 2012-11-07T16:11:36.830 回答
5

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

因此,当用 实例化时int&,您的构造函数是有效的FrontBackBuffer(int&, int&),它按给定的方式工作。

这是为什么许多人会使用T const而不是的示例const T,以更清楚地说明替换是如何发生的,并允许他们从右到左阅读 cv 限定符。

于 2012-11-07T16:11:46.837 回答
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)
  {
  };

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

Now this isn't perfect. This prevents temporary arguments to FrontBackBuffer from being moved, and passes even small cheap to copy types (like char) by reference instead of by value. There are standard C++0x techniques to do this that are a bit awkward to write if you care.

于 2012-11-07T16:24:42.493 回答
0

FrontBackBuffer::m_Front是在您的模板实例化TBufferTypeFront中转换为的类型。int&分配给int&.

于 2012-11-07T16:11:56.800 回答