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