Неверный шаблон, который не требует преобразования, всегда лучше соответствует. То есть, если бы это были единственные определения min()
, проблем не было бы (например, переименования функции min
на что-то другое устранило бы двусмысленность). Неопределенность между template <typename T> T const& std::min(T const&, T const&)
и вы templatized версии. Другой исправление удалить с помощью декларации и явного указания имен из пространства имен std
, то есть следующий код компилируется нормально:
#include <iostream>
#include <string>
template <class T> T min(T a, T b) {
return a < b? a: b;
}
std::string min(std::string str1, std::string str2) {
return str1.length() < str2.length()? str1: str2;
}
int main()
{
int n=12, p=15;
std::string str1= "monsieur", str2= "bonjour" ;
std::cout << min(n,p) << "\n";
std::cout << min(str1, str2) << "\n";
}
Пожалуйста, обратите внимание, что версия вашего min()
std::string
является не специализации, но перегрузка! При вызове функции, как вы это делали, это не имеет значения, и она выберет версию, как ожидалось. Однако, при вызове функции в то время как явное указания аргумента шаблона не будет:
min(str1, str2); // calls string overload
min<std::string>(str1, str2); // calls the function template (*)
(*) На самом деле, min<std::string>(str1, str2)
, опять же, неоднозначно с версией из имен std
из-за аргумент зависимого взгляд вверх; если бы он был назван по-разному, он бы назвал версию шаблона.
Если вы хотите действительно специализировать функцию, можно было бы написать что-то вроде этого:
template <> std::string min<std::string>(std::string, std::string) { ... }
Тем не менее, вот несколько случайных заметок о программе, не связанные с неоднозначностью и специализации:
- В C++
main()
всегда должно быть объявлено о возврате int
. Разрешено опускать оператор return в main()
, но некоторые компиляторы не получают этого права. Для портативного кода лучше всего использовать возврат int
и просто вернуть 0
(или EXIT_SUCCESSdeclared in <stdlib.h>
).
Вы почти наверняка хотите передать эти аргументы по ссылке const
: копирование строк не так дорого, особенно для небольших std::string
(поскольку современные реализации std::string
, похоже, используют небольшую оптимизацию строк), но она также не является бесплатной.Если объекты достаточно велики, это может быть проблемой производительности.
- Я предполагаю, что это всего лишь тест для игры с перегрузкой/специализацией. В противном случае,
std::string
версия min()
не рекомендуется, так как ведет себя непредсказуемым образом. - ваши тестовые строки плохо выбраны, потому что они не показывают, что фактически используется перегрузка/специализация.
сильно злоупотребляет и делает что-то другое, чем большинство людей думает, что это делает: в дополнение к вставке символа новой строки ('\ n') он также сбрасывает std :: ostream
. Это последняя неожиданная неожиданность, и я обнаружил, что она создает серьезные проблемы с производительностью довольно часто. Если вы действительно не собираетесь очищать поток, просто напишите \ n
.
Сообщите нам точные сообщения об ошибках и строки, на которые они ссылаются (в противном случае мы можем только догадываться, так как ваш примерный код, вероятно, не совсем минимальный). –
Использование min как имя, вероятно, вызовет проблемы, попробуйте сначала что-то вроде «бла», которое не будет сталкиваться со стандартными идентификаторами. – Gary