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
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'm practicing templates in Visual Studio 2013 from a not so well written C++ book and I receive the following compiler errors respectively, "error C4430: missing type specifier - int assumed. Note: C++ does not support default-int" and "error C2143: syntax error : missing ',' before '<'".
Both refer me to line 10 which is...
std::ostream& operator<< (std::ostream&, const Array<T>&);
The desired behavior of my code is to show the creation and destruction of temporary Animal objects using templates.
The troubleshooting steps I have tried so far include substituting std::iostream& with int in my return type and first parameter type of line 10. After doing so the error messages remained the same. This seemed to suggest that the problem may be the second parameter type. I then added the keyword typename to the second parameter of my overloading operator function (operator<<) on line 10 and the error still persisted.
Line 10 can be found in the header file below.
//Array.h
#ifndef ARRAY_H
#define ARRAY_H
#include <iostream>
#include "Animal.h"
const int DefaultSize = 3;
template <typename T>
std::ostream& operator<< (std::ostream&, const Array<T>&);
template <typename T> // declare the template and the paramenter
class Array // the class being parameterized
{
public:
Array(int itsSize = DefaultSize);
Array(const Array &rhs);
~Array() { delete[] pType; }
// operators
Array& operator=(const Array&);
T& operator[](int offSet) { return pType[offSet]; }
const T& operator[](int offSet) const { return pType[offSet]; }
// accessors
int GetSize() const { return itsSize; }
// friend function
friend std::ostream& operator<< (std::ostream&, const Array<T>&);
private:
T *pType;
int itsSize;
};
template <typename T>
Array<T>::Array(int size = DefaultSize) :itsSize(size)
{
pType = new T[size];
for (int i = 0; i < size; i++)
pType[i] = static_cast<T>(0);
}
Array<Animal>::Array(int AnimalArraySize) :itsSize(AnimalArraySize)
{
pType = new Animal[AnimalArraySize];
}
template <typename T>
Array<T>::Array(const Array &rhs)
{
itsSize = rhs.GetSzie();
pType = new T[itsSize];
for (int i = 0; i < itsSize; i++)
pType[i] = rhs[i];
}
template <typename T>
Array<T>& Array<T>::operator=(const Array &rhs)
{
if (this == &rhs)
return *this;
delete[] pType;
itsSize = rhs.GetSize();
pType = new T[itsSize];
for (int i = 0; i < itsSize; i++)
pType[i] = rhs[i];
return *this;
}
template <typename T>
std::ostream& operator<< (std::ostream& output, const Array<T> &theArray)
{
for (int i = 0; i < theArray.GetSize(); i++)
output << "[" << i << "]" << theArray[i] << std::endl;
return output;
}
#endif
Here's the rest of my code from my book for your reference.
//Animal.h
#ifndef ANIMAL_H
#define ANIMAL_H
#include <iostream>
class Animal
{
public:
// constructors
Animal();
Animal(int);
~Animal();
// accessors
int GetWeight() const { return itsWeight; }
void SetWeight(int theWeight) { itsWeight = theWeight; }
// friend operators
friend std::ostream& operator<<(std::ostream&, const Animal&);
private:
int itsWeight;
};
#endif
//Animal.cpp
#include "Animal.h"
#include <iostream>
Animal::Animal() :itsWeight(0)
{
std::cout << "animal() ";
}
Animal::Animal(int weight) : itsWeight(weight)
{
std::cout << "animal(int) ";
}
Animal::~Animal()
{
std::cout << "Destroyed an animal...";
}
//Main.cpp
#include <iostream>
#include "Animal.h"
#include "Array.h"
std::ostream& operator<<(std::ostream&, const Animal&);
void IntFillFunction(Array<int>& theArray);
void AnimalFillFunction(Array<Animal>& theArray);
int main()
{
Array<int> intArray;
Array<Animal> animalArray;
IntFillFunction(intArray);
AnimalFillFunction(animalArray);
std::cout << "intArray...\n" << intArray;
std::cout << "\nanimalArray...\n" << animalArray << std::endl;
std::cin.get();
return 0;
}
std::ostream& operator<<(std::ostream& theStream, const Animal& theAnimal)
{
theStream << theAnimal.GetWeight();
return theStream;
}
void IntFillFunction(Array<int>& theArray)
{
bool Stop = false;
int offset, value;
while (!Stop)
{
std::cout << "Enter an offset (0-9) and a value. ";
std::cout << "(-1 to stop): ";
std::cin >> offset >> value;
if (offset < 0)
break;
if (offset > 9)
{
std::cout << "***Please use values between 0 and 9.***\n";
continue;
}
theArray[offset] = value;
}
}
void AnimalFillFunction(Array<Animal>& theArray)
{
Animal *pAnimal;
for (int i = 0; i < theArray.GetSize(); i++)
{
pAnimal = new Animal(i * 10);
theArray[i] = *pAnimal;
delete pAnimal;
}
}
I've tried my best to keep this question on topic by providing you with the desired behavior of the program, a specific problem or error and the shortest code necessary to reproduce it. All of which are requirements for debugging help as documented in the Help Center page.
I'm new to this website, and if my question is still off-topic, please let me know how I can change my question to be more on topic or inform me of a better place to ask my question. - Thank you
This function is declared before the Array class is declared (i.e., the compiler has never seen that type and doesn't know what it is, hence your error).
template<typename> class Array; // Add this forward declaration
template <typename T>
std::ostream& operator<< (std::ostream&, const Array<T>&);
Edit
I just noticed that the operator<< is declared before the Array class and as a friend function within the Array class. You could just remove the declaration at the top.
Edit 2
Array.h
I removed the following items
#include "Animal.h"
template <typename T>
std::ostream& operator<< (std::ostream&, const Array<T>&);
Array<Animal>::Array(int AnimalArraySize) :itsSize(AnimalArraySize)
{
pType = new Animal[AnimalArraySize];
}
Updated the friend function declartion to be
template<typename T> // This is not a member function so must be declared as a template
friend std::ostream& operator<< (std::ostream&, const Array<T>&);
Animal.h
This class has the friend function but it's not implemented in the cpp file. I moved the definition from the main.cpp into Animal.cpp
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);