Почему моя перегруженная шаблонная функция продвигается по-другому, чем не шаблонная функция. - PullRequest
4 голосов
/ 01 января 2012

У меня есть перегруженная функция, которая работает правильно.(е в примере).Когда я конвертирую его в шаблонную версию одной и той же вещи, он ломается, всегда вызывая T & version, а не T *.(t в примере) Когда я делаю неконстантную версию функции шаблона, она работает как положено.(t2 в примере) Это происходит как в VS2010, так и в g ++ 4.6.2.Отличаются ли продвижения по правилам const, или это какая-то ошибка.

#include <iostream>
using namespace std;

int f(const int&x){return 1;}
int f(const int*x){return 2;}

template <class T> int t(const T &x){return 3;}
template <class T> int t(const T *x){return 4;}

template <class T> int t2(T &x){return 5;}
template <class T> int t2(T *x){return 6;}

int main(int argc, char ** argv){
    int x=0;
    cout<<f(x)<<endl;
    cout<<f(&x)<<endl;
    cout<<t(x)<<endl;
    cout<<t(&x)<<endl;
    cout<<t2(x)<<endl;
    cout<<t2(&x)<<endl;
    return 0;
}

вывод

1
2
3
3
5
6

Ответы [ 2 ]

5 голосов
/ 01 января 2012

Ваш int x не const. Таким образом, &x дает int*. Вот две функции-кандидата:

  • int t<int*>(T const&) (эквивалентно int t<int*>(int * const&)) <- T равно <code>int*; требуется 0 преобразований
  • int t<int>(T const*) (эквивалентно int t<int>(int const*)) <- T равно <code>int; требуется преобразование из int* в int const*

Лучшее совпадение, то есть без преобразования, выбрано. Это справочная версия.

2 голосов
/ 01 января 2012

В этих двух случаях:

cout<<t(x)<<endl;
cout<<t(&x)<<endl;

перегрузка template <class T> int t(const T &x) выбирается компилятором, потому что T может быть удовлетворено int и int * соответственно.

В этом случае:

cout<<t2(&x)<<endl;

перегрузка template <class T> int t2(T &x) не выбрана, поскольку она не может быть удовлетворена.Вы не можете привязать ссылку к временному (rvalue), и &x является временным.

...