2015-09-08 7 views
1
#include <iostream> 
using namespace std; 
template <typename T> 
T max(T x, T y) 
{ 
    return (x > y) ? x : y; 
} 
int main() 
{ 
    cout << max(3, 7) << std::endl; 
    cout << max(3.0, 7.0) << std::endl; 
    cout << max(3, 7.0) << std::endl; 
    return 0; 
} 

Я Ожидая Instance Макса здесьПочему вызов функции шаблона неоднозначен?

cout << max(3, 7) << std::endl; // max (int, int) 
cout << max(3.0, 7.0) << std::endl; // max (double, double) 
cout << max(3, 7.0) << std::endl; // max(int, double) 

Тогда в чем проблема? Почему я получаю

11 25 [Error] call of overloaded 'max(double, double)' is ambiguous

+3

Повторите попытку без использования пространства имен std для удаления источника путаницы. – juanchopanza

+0

@juanchopanza все тот же .. –

+0

Сделайте это в любом случае. Исправьте свой код и опубликуйте сообщение об ошибке. – juanchopanza

ответ

2

Если вы полностью просмотрите ошибку компиляции, вы увидите, почему. Вот что GCC 5.2 дает мне:

main.cpp: In function 'int main()': 
main.cpp:10:21: error: call of overloaded 'max(int, int)' is ambiguous 
    cout << max(3, 7) << std::endl; 
        ^
main.cpp:4:3: note: candidate: T max(T, T) [with T = int] 
T max(T x, T y) 
^
In file included from /usr/local/include/c++/5.2.0/bits/char_traits.h:39:0, 
       from /usr/local/include/c++/5.2.0/ios:40, 
       from /usr/local/include/c++/5.2.0/ostream:38, 
       from /usr/local/include/c++/5.2.0/iostream:39, 
       from main.cpp:1: 
/usr/local/include/c++/5.2.0/bits/stl_algobase.h:219:5: note: candidate: constexpr const _Tp& std::max(const _Tp&, const _Tp&) [with _Tp = int] 
    max(const _Tp& __a, const _Tp& __b) 
    ^

В принципе, есть две max функции - ваши и std::max, занесенная некоторой цепь других #include с от <iostream>. Последнее определяется путем поиска из-за вашего

using namespace std; 

Эффективно, мы имеем:

template <typename T> T max(T, T);      // yours 
template <typename T> T const& max(T const&, T const&); // std 

Ни лучше, чем другие, следовательно, неоднозначен. Это отличная причина для avoid using namespace std. Или отличная причина не изобретать колесо, когда речь идет о стандартных библиотечных функциях - просто используйте std::max. Или оба.


С другой стороны, это один

max(3, 7.0) 

потерпит неудачу, независимо как отказ шаблона дедукции. Это выведет T как int для первого аргумента, а T - double для второго - но может быть только один T! Вам нужно будет явно позвонить либо max<int>(3, 7.0), либо max<double>(3, 7.0), чтобы обойти ошибку дедукции, в зависимости от того, какой из двух аргументов вы хотите применить.

+0

, который является лучшим компилятором? Я слышал о том, как загрузить и использовать его в GCC? –

+0

@LetDoit Нет лучшего компилятора. Я просто представил образец вывода, чтобы указать, что вывод компилятора является ценным. Если вы хотите использовать gcc, вы можете просто google gcc. – Barry

+0

Здесь http://codepaste.net/rkh612 почему я не получаю правильный результат в два раза? –

1

Линия

using namespace std; 

делает вещи сложными, конечно. Однако даже после удаления этой строки проблема продолжает существовать.

Звонок max(3, 7.0) может быть разрешен до max<int> или max<double>. Для решения проблемы max<int> a double необходимо преобразовать в int. Чтобы решить проблему max<double>, код int должен быть преобразован в double. Поскольку оба требуют преобразования, и одно преобразование не может быть присвоено более высокое приоритет, чем другое, компилятор не может решить, какой из них использовать.

Вам нужно будет указать, какую версию max вы хотите использовать.

max<int>(3, 7.0) будет преобразовывать 7.0, a double, в int.

max<double>(3, 7.0) преобразует 3, int, в double.

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