Reputation: 47
I have some (simple looking?) problem with the variable declaration in template friend operator overloading. The compiler gives me a message:
main.cpp|103|error: ‘ptemp’ was not declared in this scope|
Code:
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;
};
}
Compilers gives message that there is no declarated "ptemp" when I do a declaration. The same is when I erase initialization of ptemp. I can't understand what is wrong in this declaration. I will be grateful for any suggestions.
Upvotes: 1
Views: 88
Reputation: 45675
The name Sequence<I,K>::Data
depends on the definition of I
and K
: the compiler can't know if Data
is a type or a non-type (i.e. a value) in the template instance Sequence<I,K>
. So you need to tell the compiler that it is a type by prepending the keyword typename
, otherwise it assumes it is a non-type, so the line is parsed as a multiplication of two values, of which the second isn't known. For a detailed explanation please refer to "Where and why do I have to put the “template” and “typename” keywords?".
typename Sequence<I,K>::Data *ptemp (cop.pHead);
If you can use C++11, you can replace the full type with auto
:
auto ptemp = cop.pHead;
Also, you can put the friend non-member definition directly inside the class (which does not make it a member!). Then you can refer to Sequence<I,K>
simply with Sequence
and to your sub-type Data
simply as Data
:
public:
friend ostream &operator << (ostream& stream, const Sequence &cop)
{
Data *ptemp (cop.pHead);
...
}
Upvotes: 0
Reputation: 96241
The problem appears to be that Sequence<I,K>::Data
is a dependent name and the compiler needs help from the typename
keyword to know what to do. So you would need to say typename Sequence<I,K>::Data *ptemp(cop.pHead);
instead. I can't figure out how it's interpreting it without the keyword though (my first guess, as a function declaration via most vexing parse doesn't appear to be correct as changing to an = in the initialization didn't fix it).
Also as an aside it appears that your inline friend
declaration may be a compiler-specific extension that should probably be avoided. I had to make multiple changes to your code to get to the point of reproducing the error in the question with g++ 4.5.
Upvotes: 2
Reputation: 310990
Try the following
typename Sequence<I,K>::Data *ptemp (cop.pHead);
Upvotes: 3