Шаблон пренебрегает const (почему?)

Кто-нибудь знает, почему это компилируется ??

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. Почему он даже позволяет мне это скомпилировать? Разве не должно быть ошибки, что я не могу присвоить константную ссылку неконстантной ссылке?

7

Решение

Чтобы код делал то, что вы хотите, он должен читать:

  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, которые немного неудобно писать, если вам не все равно.

2

Другие решения

Дело в том, что если тип T является int&тогда тип const T не является const int&, но int & const, Недопустимая константа верхнего уровня для ссылки игнорируется в подстановках шаблонов и результатах typedef.

Если, с другой стороны T является const int, затем T& является const int&

13

Когда TypeBufferFront является int&, const TBufferTypeFront эквивалентно int& constгде const игнорируется при замене шаблона, так как все ссылки являются постоянными, даже если то, на что они ссылаются, не является.

Итак, когда создается экземпляр с int&Ваш конструктор эффективно FrontBackBuffer(int&, int&), который работает как дано.

Это пример того, почему многие люди будут использовать T const вместо const T, чтобы прояснить, как происходит замена, а также позволить им читать cv-квалификаторы справа налево.

5

FrontBackBuffer::m_Front имеет тип TBufferTypeFront что переводится как int& в вашем экземпляре шаблона. Там нет ничего плохого в назначении на int&,

0
По вопросам рекламы [email protected]