Переменная не объявлена, даже если

У меня есть (простой взгляд?) Проблема с объявлением переменной в перегрузке оператора шаблона.
Компилятор выдает мне сообщение:

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.
Я не могу понять, что не так в этой декларации. Буду благодарен за любые предложения.

1

Решение

Попробуйте следующее

typename Sequence<I,K>::Data *ptemp (cop.pHead);
3

Другие решения

Проблема в том, что Sequence<I,K>::Data является зависимым именем, и компилятору нужна помощь от typename Ключевое слово, чтобы знать, что делать. Так что вам нужно сказать typename Sequence<I,K>::Data *ptemp(cop.pHead); вместо. Я не могу понять как хотя он интерпретирует его без ключевого слова (мое первое предположение, что объявление функции через самый неприятный синтаксический анализ кажется неправильным, поскольку изменение на = в инициализации не исправило это).

Также как в стороне, кажется, что ваш встроенный friend Объявление может быть специфичным для компилятора расширением, которого, вероятно, следует избегать. Мне пришлось сделать несколько изменений в вашем коде, чтобы добраться до точки воспроизведения ошибки в вопросе с g ++ 4.5.

2

Имя 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);
...
}
0
По вопросам рекламы [email protected]