2012-01-25 4 views
3

Я пытаюсь скомпилировать код Microsoft Visual C++ с помощью g ++. Теперь я столкнулся с ошибкой компилятора, которую я действительно не понимаю. (Упрощенно) код выглядит следующим образом:g ++ ошибка компилятора с шаблоном базового класса

template<int X> struct A { 
    template<class Ret> static Ret call() { 
     return 0; 
    } 
}; 

template<int X> struct B : A<X> { 
    int f() { 
     return A<X>::call<int>(); 
    } 
}; 

Когда я пытаюсь скомпилировать это с г ++ (версия 4.4.5), я получаю следующее сообщение об ошибке:

main.cpp: In member function int B<X>::f(): 
main.cpp:16: error: expected primary-expression before int 
main.cpp:16: error: expected ; before int 
main.cpp:16: error: expected unqualified-id before > token 

Если удалить тип шаблона (Ret) из метода A :: call, код компилируется просто отлично. Кто-нибудь может понять, что здесь не так?

Спасибо!

+0

возможно дубликат [Где и почему я должен поставить «шаблон» и «TYPENAME» ключевые слова?] (Http://stackoverflow.com/questions/610245/where-and-why-do- i-have-to-put-the-template-and-typename-keywords) –

ответ

5

Вам нужно template ключевое слово:

return A<X>::template call<int>(); 

call является зависимым именем, а это означает, что его значение зависит от параметра шаблона, который не известен, когда процесс компилятора f(). Вы должны указать, что call является шаблоном функции, префиксное с помощью ключевого слова template.

То же самое происходит, когда вы пытаетесь получить доступ к вложенному типу: вам нужно добавить typename ключевое слово, чтобы указать, что имя обозначает тип:

template <typename T> 
struct A { typedef int type; }; 

template <typename T> 
void f() 
{ 
    typename A<T>::type i = 0; // notice "typename" here 
} 

А иногда даже нужно смешать как:

template <typename T> 
struct A 
{ 
    template <typename U> 
    struct inner { }; 
}; 

template <typename T> 
void f() 
{ 
    typename A<T>::template inner<int> var; 
} 

использование этих двух ключевых слов подробно разъясняется в ответах на этот вопрос: Where and why do I have to put the “template” and “typename” keywords? (спасибо @ Бьерн Pollex для нахождения ссылки).

+0

[Этот вопрос] (http://stackoverflow.com/questions/610245/) содержит подробное объяснение, когда и почему это необходимо. –

+0

@ BjörnPollex: Спасибо, я действительно искал этот точный вопрос :)! –

5

A - это шаблон, и, не зная X, компилятор не может определить содержимое A<X>. Особенно он не знает, что call станет шаблоном.

Сказать, что для компилятора вы должны использовать ключевое слово template:

template<int X> struct B : A<X> { 
    int f() { 
     return A<X>::template call<int>(); 
    } 
}; 
3

Вы должны указать, что функция вы вызываете шаблон, так как это часть шаблона класса. Компилятор не знает, что любой заданный A<X> имеет функцию шаблона с именем call, и поэтому вам нужно помочь.

template<int X> struct B : A<X> { 
    int f() { 
     return A<X>::template call<int>(); 
    } 
}; 
Смежные вопросы