C ++ - создание шаблона с ссылочным типом - PullRequest
13 голосов
/ 10 ноября 2010

Я немного слышал о проблеме "ссылка-ссылка" и это разрешение.Я не очень хорошо разбираюсь в терминологии комитета C ++, но я понимаю, что аннотация "Moved to 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> (по крайней мере, в соответствии с разрешением Страуструпа)?

Ответы [ 2 ]

3 голосов
/ 10 ноября 2010

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

[Редактировать] Только что нашел хороший ответ по этому вопросу.

1 голос
/ 10 ноября 2010

Интересно, что когда я компилирую ваш код (Visual C ++ 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, определенное в упомянутом вами DR, означает, что const ref становится простым неконстантным ref в шаблоне. Моя проблема в том, что я не понимаю, почему второй f не просто игнорируется.

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

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

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

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

РЕДАКТИРОВАТЬ: Если подумать, то неудивительно, что 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>          ]

Я даже не уверен, что это как-то связано с ДР.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...