2010-11-10 4 views
13

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

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

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 ИНТ &). То, что я не получаю, это случай C<int&>: не должен ли он генерировать точно такой же код, как C<int> (по крайней мере, согласно резолюции Страустрапа)?

+0

Какой компилятор вы используете? –

+0

vs2010 генерирует ту же ошибку (в то время как vs2008 сообщает о недопустимой ошибке ref-to-ref) –

+0

это связано с тем, что динамическое/статическое приведение не допускается со ссылками на типы."'doubl & d = dynamic_cast (someintvariable)'" приводит к 'static_cast': не может преобразовать из 'int' в 'double &' в MSVC –

ответ

3

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

[Изменить] Всего найдено nice answer по этой проблеме.

+0

Еще одно интересное: http://groups.google.com/group/comp.std.c++/browse_thread/thread/ac9ba419a0d95b2d – icecrime

+0

Это приятный улов !!! –

+0

Спасибо, это прекрасно объясняет поведение компилятора во всех случаях, упомянутых мной и Стивом Таунсендом. – jhh

1

Интересно, что при компиляции кода (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; 
} 

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

Если изменить C так, что второй е является const -qualified, это сейчас составляет:

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

Подразумевается, кажется, что, когда C инстанцируется const ничего (реф или нет), два 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.

+0

Теперь я думаю, что это странно ... Ваш пример на самом деле не имеет никакого отношения к ref-to-ref; в то время как C в вопросе не имеет ничего общего с const ... –

+0

@lz_prgmr - Я даже не уверен, что мой пример имеет значение, кроме идентичной ошибки компилятора, которую он генерирует. Я надеюсь переместить дискуссию по некоторым, это все. Я думаю, если конкретный 'T' действительно разрешает обе перегрузки' f', ожидается ошибка компилятора - это не будет игнорировать одинаково хорошее совпадение. Почему каждый из них считается «одинаково хорошим», это вопрос, на который я не могу ответить. –

Смежные вопросы