У меня есть (простой взгляд?) Проблема с объявлением переменной в перегрузке оператора шаблона.
Компилятор выдает мне сообщение:
main.cpp | 103 | ошибка: «ptemp» не был объявлен в этой области |
Код:
template <typename K, typename I>
class Sequence
{
private:
struct Data
{
K key;
I data;
Data *pnext;
};
Data *pHead;
public:
//(...)
friend ostream &operator << <I,K> (ostream&, const Sequence<I,K>&);
};template <typename I, typename K>
ostream &operator << (ostream& stream, const Sequence<I,K> &cop)
{
Sequence<I,K>::Data *ptemp (cop.pHead); ///here is the error (?)
stream << "-------------- PRINT BEGINS ---------------" << endl;
if (!ptemp) //there is no elements
{
stream << "The list is empty, there is nothing to print!" << endl;
stream << "-------------- PRINT ENDS ---------------" << endl << endl;
return stream;
};
}
Компиляторы выдают сообщение о том, что при объявлении нет объявленного ptemp. То же самое, когда я стираю инициализацию ptemp.
Я не могу понять, что не так в этой декларации. Буду благодарен за любые предложения.
Попробуйте следующее
typename Sequence<I,K>::Data *ptemp (cop.pHead);
Проблема в том, что Sequence<I,K>::Data
является зависимым именем, и компилятору нужна помощь от typename
Ключевое слово, чтобы знать, что делать. Так что вам нужно сказать typename Sequence<I,K>::Data *ptemp(cop.pHead);
вместо. Я не могу понять как хотя он интерпретирует его без ключевого слова (мое первое предположение, что объявление функции через самый неприятный синтаксический анализ кажется неправильным, поскольку изменение на = в инициализации не исправило это).
Также как в стороне, кажется, что ваш встроенный friend
Объявление может быть специфичным для компилятора расширением, которого, вероятно, следует избегать. Мне пришлось сделать несколько изменений в вашем коде, чтобы добраться до точки воспроизведения ошибки в вопросе с g ++ 4.5.
Имя Sequence<I,K>::Data
зависит от определение I
а также K
: компилятор не может знать, если Data
является типом или нетипом (то есть значением) в экземпляре шаблона Sequence<I,K>
, Поэтому вы должны сообщить компилятору, что это тип, добавив ключевое слово typename
в противном случае предполагается, что это не тип, поэтому строка анализируется как умножение двух значений, второе из которых неизвестно. Для подробного объяснения, пожалуйста, обратитесь к «Где и почему я должен поставить ключевые слова» template «и» typename «?».
typename Sequence<I,K>::Data *ptemp (cop.pHead);
Если вы можете использовать C ++ 11, вы можете заменить полный тип на auto
:
auto ptemp = cop.pHead;
Кроме того, вы можете поместить определение друга, не являющегося членом, прямо в класс (что делает не сделать это членом!). Тогда вы можете обратиться к Sequence<I,K>
просто с Sequence
и к вашему подтипу Data
просто как Data
:
public:
friend ostream &operator << (ostream& stream, const Sequence &cop)
{
Data *ptemp (cop.pHead);
...
}