2015-05-13 3 views
0

Вот немного кода:шаблон функции перегрузки с сопзЬ

template<class T> 
inline void bar(T& t) { 
    foo(t); // intention is that foo() is found by ADL 
} 

struct Wig { 
    int i; 
}; 

void foo(int){ } 

// some convenience overload 
inline void bar(const Wig& w) { foo(w.i); } 

// The bit that if uncommented, "fixes" the problem 
//inline void bar(Wig& w) { foo(w.i); } 

int main() 
{ 
    Wig w; 
    bar(w); 
    return 0; 
} 

Clang 3,5 и 4,7 Gcc, выплюнуть следующее сообщение об ошибке:

template-function-overload.cpp:12:4: error: no matching function for call to 'foo' 
    foo(t); 
    ^~~ 
template-function-overload.cpp:29:4: note: in instantiation of function template specialization 
     'bar<Wig>' requested here 
    bar(w); 
^
template-function-overload.cpp:19:6: note: candidate function not viable: no known conversion from 
     'Wig' to 'int' for 1st argument 
void foo(int){ } 
    ^

Так это не выглядит как компилятор вопрос.

Также, комментируя неконстантную перегрузку, исправлена ​​ошибка.

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

+1

Перед тем, как позвонить, вам нужно объявить 'foo'. – juanchopanza

+0

Это неверно для контекста шаблона, и не работает ADL. А также обратите внимание, что при неконстантной перегрузке код является законным. – Nick

+0

Неважно. Вы это прекрасно понимаете. – juanchopanza

ответ

6

Для bar(w) вызова, разрешение перегрузки сравнивает

void bar<Wig>(Wig&); // instantiated from the template 
void bar(const Wig &); 

Связывание с ссылкой на менее квалифицирован CV-типа лучше ([over.ics.rank], пуля 3.2.6), так что первый подпись выбрана. Этот шаблон пытается вызвать foo на Wig, но нет такой вещи, поэтому ошибка.

С дополнительным неконстантной перегрузкой, мы теперь сравнением (плюс const Wig &, что хуже, чем либо):

void bar<Wig>(Wig&); // instantiated from the template 
void bar(Wig&); 

Типы параметров идентичны, так что два неразличимы ранжированиями последовательностей преобразования, и вместо этого тай-брейкер в [over.match.best] bullet 1.6 выбирает не шаблон по специализации шаблона функции.

+0

Отличный ответ! Спасибо за указатели на стандарт и объяснение того, как шаблон входит в рейтинг. – Nick

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