I have a template class MGraph<T>with a member function print_relation and a friend function which is ostream& operator<<(ostream& os, const MGraph<T>& other)
I follwed the instructions here and wrote this code:
template<class T>
ostream& MGraph<T>::print_relation(ostream& os) const
{
for (VertexId i = 0; i < max_size; i++)
{
for (VertexId j = 0; j < max_size; j++)
{
os << relation[i][j] << ' ';
}
os << endl;
}
return os;
}
...
template<class T>
ostream& operator<<(ostream& os, const MGraph<T>& other)
{
os << other.print_relation(os);
return os;
}
I get the following error when compiling:
1>main.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 MGraph<bool> const &)" (??6#YAAAV?$basic_ostream#DU?$char_traits#D#std###std##AAV01#ABV?$MGraph#_N###Z) referenced in function "void __cdecl exec<bool>(class MGraph<bool> *)" (??$exec#_N##YAXPAV?$MGraph#_N###Z)
It appears 4 times, once for every data type (int, char, double, bool).
What did I do wrong?
In your overload of operator<<, you are doing this
os << other.print_relation(os);
And since MGraph<T>::print_relation returns std::ostream&, that is not valid. operator<< is not overloaded in such way, that it takes std::ostream& on RHS.
So, just remove the os <<.
template<class T>
ostream& operator<<(ostream& os, const MGraph<T>& other)
{
other.print_relation(os);
return os;
}
Related
I've overloaded << operator to print the address in pointer member of a class. However, it throws the following error (using Visual Studio 2017). Using a normal class method does the job.
Any leads?
Error:
error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl IntroSmartPointers::operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class IntroSmartPointers::AutoPtr<class IntroSmartPointers::Resource> const &)" (??6IntroSmartPointers##YAAEAV?$basic_ostream#DU?$char_traits#D#std###std##AEAV12#AEBV?$AutoPtr#VResource#IntroSmartPointers###0##Z) referenced in function "void __cdecl IntroSmartPointers::main(void)" (?main#IntroSmartPointers##YAXXZ)
Code:
#include <iostream>
using namespace std;
namespace SmartPointers {
template<class T>
class AutoPtr {
private:
T* m_ptr;
public:
// constructor
AutoPtr(T* ptr = nullptr)
: m_ptr(ptr)
{}
// destructor
~AutoPtr() {
delete m_ptr;
}
friend ostream& operator<<(ostream& out, const AutoPtr<T>& ptr);
};
template<class T>
ostream& operator<<(ostream& out, const AutoPtr<T>& ptr) {
out << ptr.m_ptr;
}
class Resource {
public:
Resource() { cout << "Resource(): acquired\n"; }
~Resource() { cout << "~Resource: destroying...\n"; }
void sayHi() {
cout << "Hi\n";
}
};
}
void main() {
SmartPointers::AutoPtr<Resource> ptr{ new Resource{} };
cout << ptr << endl;
}
Your friend declares non-template operator.
In this case, you can define a friend function inside of the class body, or try the following:
template<typename T>
class AutoPtr {
// ...
template<typename U>
friend ostream& operator<<(ostream& out, const AutoPtr<U>& ptr);
};
template<class T>
ostream& operator<<(ostream& out, const AutoPtr<T>& ptr) {
out << ptr.m_ptr;
return out; // You missed this part too
}
see Template friend operators section in https://en.cppreference.com/w/cpp/language/friend
And main should return int instead of void.
I tried to search but I couldn't find a solution and what is the meaning of the problem.
friend ostream & operator<<(ostream &os, const BST<T> &rhs);
void helperFunc(ostream & os, Node<T> *root) const;
and the definition is:
template<class T>
ostream & operator<<(ostream & os, const BST<T> &rhs)
{
rhs.helperFunc(os, rhs._root);
os << endl;
return os;
}
template<class T>
void BST<T>::helperFunc(ostream & os, Node<T> *root) const
{
if (root != NULL)
{
helperFunc(os, root->left);
os << root->value << " ";
helperFunc(os, root->right);
}
}
In main I'm using:
void main()
{
BST <int> a;
a.insert(5)
cout << a;
}
And I'm getting the following error message:
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 BST<int> const &)" (??6#YAAAV?$basic_ostream#DU?$char_traits#D#std###std##AAV01#ABV?$BST#H###Z) referenced in function _main...
Any additional info will be supplied if required.
The solution was:
template <typename U>
friend ostream & operator<<(ostream & os, const BST<U> &obj);
Overloading operator<< and operator>> in template class is a little special. Just comment this declaration and it will work:
friend ostream & operator<<(ostream &os, const BST<T> &rhs);
This is because the friend function is not a member function of the class actually. The overloaded operator<< function defined outside the class actually defines a new template function, different from that declared in the class. Although they have the same 'template class T', but indeed they are different functions. So the compile error tells you that the operator<< function of the class is not defined.
Since we have overload a new template operator<< outside the class, we can just get rid of the friend function declared in the class. The follow codes will work and I change some other functions for well explanation:
#include <iostream>
using namespace std;
template<class T>
class Node {
};
template<class T>
class BST {
public:
// friend ostream & operator<<(ostream & os, const BST<int> &rhs);
void helperFunc(ostream & os, Node<T> *root) const;
};
template<class T>
ostream & operator<<(ostream & os, const BST<T> &rhs)
{
cout << "success" << endl;
// rhs.helperFunc(os, rhs._root);
// os << endl;
return os;
}
template<class T>
void BST<T>::helperFunc(ostream & os, Node<T> *root) const
{
if (root != NULL)
{
helperFunc(os, root->left);
os << root->value << " ";
helperFunc(os, root->right);
}
}
int main()
{
BST<int> a;
// a.insert(5);
cout << a;
}
i have a template class, and when im runing the program it says
error LNK2019: unresolved external symbol "class std::basic_ostream > & __cdecl operator<<(class std::basic_ostream > &,class CSet &)" (??6#YAAAV?$basic_ostream#DU?$char_traits#D#std###std##AAV01#AAV?$CSet#H###Z) referenced in function "public: void __thiscall Menu::menu(void)" (?menu#Menu##QAEXXZ)
on any kind of data structure i try to use,
if anyone can explain to me why the overloading of printing function makes this error i'll be happy to ear about it.
template <class T> class CSet{
T* Array;
int size;
public:
CSet()
{
Array = NULL;
size = 0;
}
CSet(CSet& other){
size = other.size;
Array = new T[size];
for (int i = 0; i < size; i++)
Array[i] = other.Array[i];
}
friend ostream& operator <<(ostream& out, CSet& other);
~CSet()
{
if (size > 0)
delete[] Array;
}
};
template <class T> ostream& operator <<(ostream& out, CSet<T>& other){
out << "(";
for (int i = 0; i < other.size; i++){
if (size>1)
out << other.Array[i] < ",";
else
out << other.Array[i];
}
out << ")" << endl;
return out;
}
The friend declaration does not declare a function template, but a separate function for each instantiation of the class template. Therefore, the template you define is not the same as these functions, which remain undefined.
There are two options to fix this.
Either define the friend operator inside the class, rather than just declaring it there:
friend ostream& operator <<(ostream& out, CSet& other) {
// implementation
}
Or declare the function template before the class definition:
template <class T> class CSet;
template <class T> ostream& operator <<(ostream& out, CSet<T>&);
and declare the template to be a friend:
friend ostream& operator << <T>(ostream& out, CSet&);
^^^
I have the following C++ Header File:
namespace big_numbers
{
class bigint
{
private:
// private data
public:
// constructors and other methods
friend ostream & operator<<( ostream & out, const bigint & data )
{
out << data.str();
return out;
}
};
}
This is the only way that I found to declare and define the << operator for my class, to be used like so
bigint number("12345");
cout << number;
I tried some other things but they don't work. My application does not compile. How to overload this operator writing the declaration in a header file and the definition in a source file?
After modifying the code as in #DanielFrey answer, my IDE (Microsoft Visual Studio 2013) reports the following error:
Error 5 error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl BigNumbers::operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class BigNumbers::bigint const &)" (??6BigNumbers##YAAAV?$basic_ostream#DU?$char_traits#D#std###std##AAV12#ABVbigint#0##Z) referenced in function _wmain E:\Applications\BigNumbers\test\test.obj test_console
Like this:
// header
namespace big_numbers
{
class bigint
{
private:
// private data
public:
// constructors and other methods
friend ostream & operator<<( ostream & out, const bigint & data );
};
}
and
// implementation
#include "bignum.hh"
namespace big_numbers
{
ostream & operator<<( ostream & out, const bigint & data )
{
out << data.str();
return out;
}
}
(given the correct includes in both header and implementation file...)
To get around msvc linking issues:
class X {
public:
std::ostream& write(std::ostream&) const;
};
inline std::ostream& operator << (std::ostream& s, const X& x) {
return x.write(s);
}
I'm getting the following error from this code:
Error 1 error LNK2019: unresolved external symbol "class std::basic_ostream > & __cdecl operator<<(class std::basic_ostream > &,class Point const &)" (??6#YAAAV?$basic_ostream#DU?$char_traits#D#std###std##AAV01#ABV?$Point#N###Z) referenced in function _main G:\C++ Part II\Final Exam\Point\Point\Source.obj Point
I know this error typically means that I don't have a function defined, however, it is defined. The program compiles if I comment out the cout statement in main. I'm guessing I'm missing something with my Template designation?
#include <iostream>
using namespace std;
template <class T>
class Point{
private:
T x, y;
public:
Point(): x(0), y(0) {cout << "Default Constructor\n";};
Point(T a, T b): x(a), y(b) {cout << "Parameterized Constructor\n";};
Point(const Point &rhs);
~Point() {cout << "Destructor\n";};
friend ostream &operator<<(ostream &os, const Point<T> &X);
};
int main(){
Point <double> B;
cout << B << endl;
return 0;
}
template <class T>
Point<T>::Point(const Point &rhs)
{
x = rhs.x;
y = rhs.y;
cout << "Copy Constructor\n";
}
template <class T>
ostream &operator<<(ostream &os, const Point<T> &X)
{
os << "(" << X.x << ", " << X.y << ")";
return os;
}
The function you have declared as friend in the class isn't actually the same as the one you implemented. It's a templated function and the declaration needs to reflect that:
template <class T> friend ostream &operator<<(ostream &os, const Point<T> &X);