有人知道,为什么要编译?
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引用的错误吗?
答案 0 :(得分:13)
问题是,如果T
类型为int&
,则类型const T
不是const int&
,而是int & const
。在模板替换和typedef结果中忽略引用上的非法顶级const。
如果另一方面T
为const 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&
时没有错。