Кто-нибудь знает, почему это компилируется ??
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. Почему он даже позволяет мне это скомпилировать? Разве не должно быть ошибки, что я не могу присвоить константную ссылку неконстантной ссылке?
Чтобы код делал то, что вы хотите, он должен читать:
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
,
Теперь это не идеально. Это предотвращает временные аргументы FrontBackBuffer
от перемещения и передает даже небольшие дешевые для копирования типов (например, char
) по ссылке, а не по значению. Для этого есть стандартные методы C ++ 0x, которые немного неудобно писать, если вам не все равно.
Дело в том, что если тип T
является int&
тогда тип const T
не является const int&
, но int & const
, Недопустимая константа верхнего уровня для ссылки игнорируется в подстановках шаблонов и результатах typedef.
Если, с другой стороны T
является const int
, затем T&
является const int&
Когда TypeBufferFront является int&
, const TBufferTypeFront
эквивалентно int& const
где const игнорируется при замене шаблона, так как все ссылки являются постоянными, даже если то, на что они ссылаются, не является.
Итак, когда создается экземпляр с int&
Ваш конструктор эффективно FrontBackBuffer(int&, int&)
, который работает как дано.
Это пример того, почему многие люди будут использовать T const
вместо const T
, чтобы прояснить, как происходит замена, а также позволить им читать cv-квалификаторы справа налево.
FrontBackBuffer::m_Front
имеет тип TBufferTypeFront
что переводится как int&
в вашем экземпляре шаблона. Там нет ничего плохого в назначении на int&
,