LNK2019 error: output protected vector member of class template via ostream friend method

Hey everyone, sorry for bugging y'all again, but I've been unable to figure this one out after an hour or so. And I have a little less hair up top...

I've never worked with vectors before, and I'm trying to do a list class with a vector to hold the list items. However, when I try to overload the << operator as a friend of the class, I get an error. Here are the relevant parts of my code:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//-------------------------------myClass.h Header File
template <class T>
class myClass {

  protected:
    vector<T> items;
//------ operator << declared as friend in class
  friend ostream& operator <<(ostream&, const myClass<T>&);
};

//----------------------operator << defined as friend in myClass.h file
template <class T>
ostream& operator <<(ostream& out, const myClass<T>& list) {
  items.iterator it;
  for(it = items.begin();it <= items.end();++it) {
    if(items(it) == items.begin())
       out << items(it);
    else
       out << " " << items(it);
  }
  return out;
}


The error that is being generated is:

1
2
3
1>Driver.obj : error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl
operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class myClass<int> const &)"
(??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABV?$myClass@H@@@Z) referenced in function _main


In my Driver file, I have:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//---------------------------Driver.cpp
#include <iostream>
#include <vector>
#include "myClass.h"
  using namespace std;


int main() {
  myClass<int> list;
  int num;

  for(int i = 0;i < 10; i++) {
    cout << "\nEnter a number to insert into the vector";
    cin >> num;
    list.insert(num);
  }

  cout << list;
  return 0;

}


Any ideas as to why this is occurring? I appreciate any feedback.
Last edited on
Is operator << defined in "myClass.h" ? Template functions should always be in headers.
Yes it is. I edited the original post to better convey this information.
I just noticed that your function is pretty wrong. I wonder if that could be the cause (If the compiler can't compile a function, the linker won't find it).
Instead of items it should be list.items, vector has no member "iterator". it should be vector<T>::iterator it;
condition in the for loop should be <, not <=
What did you mean by "items(it)" it seems like you just want "it" or "*it".
Instead of items it should be list.items, vector has no member "iterator". it should be vector<T>::iterator it;
condition in the for loop should be <, not <=


So, where I have, for instance, items.begin(), it should be list.items.begin()?


What did you mean by "items(it)" it seems like you just want "it" or "*it".


I am wanting to output the element in that particular spot in the vector - kind of like iterating through an array and outputting what is in the sub-scripted location during each iteration.


1. yes

2. look, there are two ways to iterate through an array:
1
2
3
4
5
6
7
int array[5];

/*1*/
for(int i = 0; i < 5; i++) array[i]++;

/*2*/
for(int* it = &array[0]/*or just array*/; it < &array[5]/*or preferably array+5, since array[5] doesn't exist*/; it++ ) (*it)++;


vectors try to look like arrays, so the same two methods exist. If "array" is a vector, in the first case change 5 to array.size() and in the second change "int*" to vector<int>::iterator, "&array[0]" to array.begin() and "&array[5]" to array.end(). The rest remains.
Sorry for the delay in responding. I went back through the program and driver file, and had a whole slew of issues crop up. Namely, I was attempting to use vector operations (like items.end()) and such that my computer just really did NOT like. However, I have gotten those resolved (I hope...I only have a warning comparing int i to items.size() ). I'm just iterating through the vector as if it were an array.

Now, I am back to the original issue - 1 unresolved external symbol.

I have the following line declared in my class, before all other declarations

friend ostream& operator <<(ostream&, const myClass<T>&)


At the end of the header file, since I'm defining my functions in the same file instead of a separate .cpp file, I have

1
2
3
4
5
6
7
8
9
10
11
template <class T>
ostream& operator <<(ostream& out, const myClass<T>& list) {
  
  for(int i = 0;i < list.items.size();++i) {
    if(i == 0)
       out << list.items[i];
    else
       out << " " << list.items[i];
  }
  return out;
}


In the driver program, I have the following line of code:

cout << list

Where "list" is an object of class myClass.

I'm under the impression that a friend function can access protected members of the class, and items is a protected member of the class. I know I have to pass an ostream object by reference, as well as an object of what I want outputted. I believe I have kept both of these standards intact...however I have spent the better part of the evening running from funnel clouds...
Um...Okay, I'm not sure WHY this worked, so if someone could explain it to me, I would be extremely grateful.

In the declaration of the friend function within the class, I changed it to:

1
2
template <class U>
friend ostream& operator <<(ostream&, myClass<U>&);


And in the method definition, I modified it to:
1
2
3
4
5
6
7
8
9
10
11
template <class U>
ostream& operator <<(ostream& out, const myClass<U>& list) {
  
  for(int i = 0;i < list.items.size();++i) {
    if(i == 0)
       out << list.items[i];
    else
       out << " " << list.items[i];
  }
  return out;
}



Now it works...we get along like old pals now... but for some reason, before I changed "template T" to "template U" on the ostream method - had it like alllll the other methods - it threw the unresolved external error. I'm boggled. :(
Because your friend declaration originally was a non-template function, but the ostreamer you wrote was a template function. When you use the keyword "friend", you are not declaring a function. You are declaring the function to be a friend of the class. Said "function" is not a member of the class, either; it is a free function.

Therefore, when you actually declared and implemented the function below, the function you implemented was a template free function. But the friend declaration was not a template function.
Topic archived. No new replies allowed.