Подтвердить что ты не робот

С++ - создание экземпляра шаблона со ссылочным типом

Я немного слышал о проблеме ссылки на ссылку и это разрешение. Я не очень хорошо разбираюсь в терминологии Комитета С++, но я понимаю, что аннотация "Перемещено в DR" в ссылке означает, что это текущая интерпретация, которой должны придерживаться совместимые со стандартом компиляторы.

У меня есть этот пример кода, который я не могу понять:

template <typename T>
struct C {
  void f(T&) { }
  void f(const T&) { }
};

int main() {
  C<int> x;        // OK
  C<int&> y;       // compile error: f cannot be overloaded
  C<const int&> z; // compile error: f cannot be overloaded
}

Я понимаю ошибку в случае C<const int&>: используя правила из DR # 106, мы получаем два метода с одинаковой сигнатурой f (const int &). То, что я не получаю, это случай C<int&>: не должен ли он генерировать точно такой же код, что и C<int> (по крайней мере, согласно разрешению Страустрипа)?

4b9b3361

Ответ 1

Только DR означает "Отчет о дефектах", и, насколько мне известно, описанная резолюция еще не дошла до стандарта. По этой причине я считаю, что строго соответствующая реализация С++ 03 не должна компилировать этот код из-за того, что он создает ссылку на ссылку.

[Edit] Просто нашел хороший ответ по этой проблеме.

Ответ 2

Интересно, когда я компилирую ваш код (Visual С++ 10 Express), я получаю ошибки, но также когда я пробую этот более простой случай:

int main(int argc, char* argv[]) 
{
  C<int> x;        // OK
  C<const int> x1; // error C2535: 'void C<T>::f(T &)' : member function 
                   // already defined or declared
  return 0;
}

Похоже, что ref-to-ref collapsing, определенный в упомянутом вами DR, означает, что const ref становится простым не-const ref внутри шаблона. Моя проблема заключается в том, что я не понимаю, почему второй f не просто игнорируется.

Если я сменил C так, чтобы второй f был const -qualified, теперь он компилирует:

template <typename T>
struct C {
  void f(T&) { }
  void f(const T& t) const {}
};

Кажется, что подразумевается, что при C создается const что-либо (ref или нет), две перегрузки C::f просто идентичны и приводят к обнаружению дубликатов времени компиляции.

Возможно, кто-нибудь умнее меня может расшифровать цепочку более определенно здесь.

EDIT: При отражении здесь не удивительно, что T = const int& приводит к тому, что перегрузки f идентично создаются как

void f(const int&) {}

Что компилятор мне говорит:

#include "stdafx.h"

template <typename T>
struct C {
  void f(T&) { }
  void f(const T&) { }
};

int main() {
  C<const int&> z; // compile error: f cannot be overloaded
  return 0;
}

дает эту ошибку:

1>test.cpp(6): error C2535: 'void C<T>::f(T)' : member function already 
    defined or declared
1>          with
1>          [
1>              T=const int &
1>          ]
1>          test.cpp(5) : see declaration of 'C<T>::f'
1>          with
1>          [
1>              T=const int &
1>          ]
1>          test.cpp(10) : see reference to class template instantiation 
                'C<T>' being compiled
1>          with
1>          [
1>              T=const int &
1>          ]

Я даже не уверен, что это имеет какое-то отношение к DR.