2010-07-28 7 views
-1

Я следующий код:Синтаксическая ошибка с шаблоном в C++

#include <iostream> 
using namespace std; 
template<class T> 
T max(T *data,int len){ 
    int i; 
    T Max=data[0]; 

    for (int i=1;i<len;i++){ 

     if (data[i]>max){ 
      Max=data[i]; 


    } 
    } 
return Max; 

} 
int mai(){ 
    int i[]={12,34,10,9,56,78,30}; 
    int len=sizeof(i)/sizeof(i[0]); 
    cout<<max(i,len)<<"\n"; 



    return 0; 
} 

Но когда я компилирую его, я получаю следующие ошибки:

generic_max, Configuration: Debug Win32 ------ 
1>Build started 7/29/2010 1:03:25 AM. 
1>InitializeBuildStatus: 
1> Touching "Debug\generic_max.unsuccessfulbuild". 
1>ClCompile: 
1> generic_max.cpp 
1>c:\users\david\documents\visual studio 2010\projects\generic_max\generic_max\generic_max.cpp(10): error C2563: mismatch in formal parameter list 
1>   c:\users\david\documents\visual studio 2010\projects\generic_max\generic_max\generic_max.cpp(22) : see reference to function template instantiation 'T max<int>(T *,int)' being compiled 
1>   with 
1>   [ 
1>    T=int 
1>   ] 
1>c:\users\david\documents\visual studio 2010\projects\generic_max\generic_max\generic_max.cpp(10): error C2568: '>' : unable to resolve function overload 
1>   c:\users\david\documents\visual studio 2010\projects\generic_max\generic_max\generic_max.cpp(4): could be 'T max(T *,int)' 
1>   c:\program files\microsoft visual studio 10.0\vc\include\xutility(2086): or  'const _Ty &std::max(const _Ty &,const _Ty &,_Pr)' 
1>   c:\program files\microsoft visual studio 10.0\vc\include\xutility(2078): or  'const _Ty &std::max(const _Ty &,const _Ty &)' 
1> 
1>Build FAILED. 
1> 
1>Time Elapsed 00:00:00.95 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 

Пожалуйста, помогите мне решить эту проблему.

+0

Этот «вопрос» следует переименовать «пожалуйста, отлаживайте мой код». Тот факт, что это шаблон, не имеет значения. –

+0

Не связанный с вопросом: если вы всегда используете массивы (а не динамически выделенную память), вы можете заставить компилятор вычесть размер массива для вас: 'template T max (T (& ar) [N ]) 'Компилятор выведет размер для вас. –

ответ

4

C++ чувствителен к регистру.

#include <iostream> 

// Note the omission of `using namespace std;`. The declaration can 
// introduce clashes if one of your functions happen to have the same name 
// as the functions in the std namespace. 

template<class T> 
T max(T *data,int len) { 
    //int i; <-- Not needed? The for loop already has an `i` declared in it. 
    T Max=data[0]; 

    for (int i=1;i<len;i++) { 
     /****** Note `Max`, not `max` ******/ 
     // The typo in your code snippet is what's causing the C2563. 
     // `max` (in this context) refers to the function 
     // `template<class T> T max(T *data,int len)` that has been declared. 
     // `Max` refers to the variable declared in this function. 
     // (For the sake of readability, variable names should not similar 
     // to the function name). 
     if (data[i]>Max) { 
      Max=data[i]; 
     } 
    } 
    return Max; 
} 

/****** Note `main()`, not `mai()` ******/ 
int main() { 
    int i[]={12,34,10,9,56,78,30}; 
    int len=sizeof(i)/sizeof(i[0]); 
    // `cout` should be just qualified with `std::` instead of 
    // `using namespace std`. 
    std::cout<<max(i,len)<<"\n"; 
    return 0; 
} 
+0

Все верно, но это не вызывает ошибки компилятора в вопросе. Хотя я полностью озадачен тем, как эти типы ошибок опечатки могут возникать на SO ... действительно ли люди действительно перепечатывают свой код в поле вопроса, а не просто копируют? –

+0

Другая вещь, которую следует изменить, - это объявление 'int i;' в начале определения max(). Переменная 'i' объявляется локально в цикле' for', поэтому первое объявление ничего не делает. – Praetorian

+0

@Tyler, несоответствие случая в 'max' и' Max' действительно является причиной того, что ошибка 'ошибка C2563: несоответствие в формальном списке параметров'; Я просто попробовал это на VS2008. Как ни странно, я бы подумал, что ошибка будет чем-то вроде «Функция max не принимает 0 аргументов», а с шаблонами, которые знают ... Я, вероятно, должен быть счастлив, что сообщение об ошибке не охватывало 2 дюжины строк:) Что вы сказали о том, что люди перепечатывают код в SO ... это заставляет вас задаться вопросом, не так ли? Особенно функция mai() вместо main()! – Praetorian

0

если (данные [я]> макс) - изменение макс Максу

0

В строке 10, вы, вероятно, означает >Max и не >max.

4

Ваша max функция конфликтует со стандартным C++ функции std::max, потому что вы написали using namespace std в верхней части программы, которая приносит все в std пространство имен в пространство имен по умолчанию. Компилятор не может сказать, хотите ли вы позвонить max или какой-либо версии std::max.

Либо измените имя своей функции, либо удалите using namespace std и явно укажите в своей программе в пространстве имен std с std::.

+0

Это абсолютно неверно! Наиболее очевидной причиной является то, что std :: max находится в , и этот заголовок даже не включен. Даже если он включен, std :: max принимает две константные ссылки типа T, которая отличается от указателя на T и int. Когда он пишет max (i, len), компилятор знает, что i имеет тип int [] и len имеет тип int, поэтому разрешение перегрузки будет знать, какой макс вызывается. – ryaner

+0

Это не ложь. Хотя он не включил , он включил , и нет никакой гарантии, что это не будет включать в себя косвенно. Во-вторых, прочитайте сообщение об ошибке. Он указывает * явно * на 'std :: max' для двух неоднозначных перегрузок. В верхней части моей головы я не уверен, почему он не может исключить перегрузки 'std :: max' для указанных вами причин несоответствия типов, но я полагаю, что это связано с порядком, в котором компилятор считает разрешение перегрузки по сравнению с созданием шаблона.В любом случае сообщение об ошибке очень ясно говорит о том, что проблема - 'std :: max'. –

+0

Прошу прощения за мой комментарий о header =) Ты был прав. Я посмотрел сообщение об ошибке и понял, что это было вызвано в строке 10. Какова его опечатка «max». В этом случае действительно компилятор не знал бы, какой адрес функции он должен получить. На самом деле вы были совершенно правы, ваш ответ объясняет эффект его непреднамеренной опечатки. – ryaner

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