LNK2019 Error on overloaded output operator - c++

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);

Related

overloaded << operator function : unresolved external symbol error

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.

Template Binary Search Tree ostream overloading issue

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;
}

VS2015 compile error for template function with "endl" [duplicate]

This question already has answers here:
Why do stream operators return references in C++?
(3 answers)
Closed 6 years ago.
#include "stdafx.h"
#include <iostream>
using namespace std;
// move operation is not implicitly generated for a class where the user has explicitly declared a destructor
class A {
public:
friend inline void operator << (ostream &os, A& a) {
os << "done" << endl;
}
};
template <typename T>
void done(T a) {
cout << a;
}
template<typename T>
void g(T h) {
cout << h << endl;
}
int main()
{
A a;
done(a);
// g(a); // with error: "mismatch in formal parameter list" and '<<': unable to resolve function overload.
return 0;
}
As the comments, it is so weird that with 'endl', the code cannot be compiled
with error: "mismatch in formal parameter list" and '<<': unable to resolve function overload.
You should return a reference to the stream so that you can chain the function calls
friend inline std::ostream& operator << (std::ostream &os, A& a) {
os << "done" << endl;
return os;
}
Not this
friend inline void operator << (ostream &os, A& a) {
os << "done" << endl;
}
When you use
friend inline void operator << (ostream &os, A& a)
the line
cout << h << endl;
is a problem since there is no operator<< between void and endl.

error LNK2019: unresolved external symbol

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&);
^^^

Operator << overloading

I'm working on my project and I want to overload operator << which should print out my object on console.
Object is called "config" and in its template class it has 4 arrays called attribute1, attribute2. attribute3 and attribute4.
So far I've tried this :
#include "stdafx.h"
#include <string>
#include <iostream>
using namespace std;
template<typename T> class config
{
T *attribute1, *attribute2, *attribute3, *attribute4;
string attribName1, attribName2, attribName3, attribName4;
public:
config(void)
{
attribute1 = new T[3];
attribute2 = new T[3];
attribute3 = new T[3];
attribute4 = new T[3];
}
~config(void)//destruktor
{
delete [] attribute1, attribute2, attribute3, attribute4;
}
//operatory
friend ostream& operator<<(ostream &out, const config<T> &c);
};//class ends
template <typename T> ostream& operator<<(ostream &out, const config<T> &c)
{
for(int i=0;i<3;i++)
{
out<<c.attribute1[i]<<c.attribute2[i]<<c.attribute3[i]<<c.attribute2[i];
}
return out;
}
Whenever I try to compile it, it gives some kind of weird error, but I know the problem is in the operator.
This is the error it gives :
Error 1 error LNK2001: 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 config<double> const &)" (??6#YAAAV?$basic_ostream#DU?$char_traits#D#std###std##AAV01#ABV?$config#N###Z) D:\Docs\Visual Studio 2010\Projects\project_v2.obj project_v2
and:
Error 2 error LNK1120: 1 unresolved externals D:\Docs\Visual Studio 2010\Projects\project_v2.exe project_v2
And line or column isnt specified.
Here's one way to solve the problem.
Declare the operator<< function first, before config is defined. In order to declare the function, you have to forward declare the class template.
template <typename T> class config;
template <typename T> std::ostream& operator<<(std::ostream &out,
const config<T> &c);
In the class, make the function a friend by using T as the template parameter.
friend ostream& operator<< <T>(ostream &out, const config &c);
// Notice this ^^^^
// This makes sure that operator<< <int> is not a friend of
// config<double>. Only operator<< <double> is a friend of
// config<double>
Here's a working program with those changes:
#include <string>
#include <iostream>
template <typename T> class config;
template <typename T> std::ostream& operator<<(std::ostream &out,
const config<T> &c);
template <typename T> class config
{
T *attribute1, *attribute2, *attribute3, *attribute4;
std::string attribName1, attribName2, attribName3, attribName4;
public:
config(void)
{
attribute1 = new T[3];
attribute2 = new T[3];
attribute3 = new T[3];
attribute4 = new T[3];
}
~config(void)//destructor
{
delete [] attribute1;
delete [] attribute2;
delete [] attribute3;
delete [] attribute4;
}
//operator
friend std::ostream& operator<< <T>(std::ostream &out,
const config &c);
};
template <typename T> std::ostream& operator<<(std::ostream &out,
const config<T> &c)
{
for(int i=0;i<3;i++)
{
out << c.attribute1[i] << " "
<< c.attribute2[i] << " "
<< c.attribute3[i] << " "
<< c.attribute2[i] << std::endl;
}
return out;
}
int main()
{
config<double> x;
std::cout << x << std::endl;
}
Output:
0 0 0 0
0 0 0 0
0 0 0 0