I'm trying to write a binary tree to a file using a recursive function. The call to writeFile(std::string fileName)
opens the file stream and then passes it to the recursive function call, writeFile(BinNode<T> ptr, std::ofstream outFile)
. The compiler comes back with the error "attempting to reference a deleted function" when the first function calls the second function (line noted in my code. I researched the error code and I have a default constructor, a destructor so none of the functions are implicit. Any ideas would be greatly appreciated.
BinTree.h:
#ifndef BINTREE_H
#define BINTREE_H
#include <iostream>
#include <fstream>
#include "BinNode.h"
template<typename T>
class BinTree {
public:
BinTree(); // Default constructor
// Value semantics
// copy constructor
BinTree(const BinTree<T>& source);
// assignment operator
BinTree<T>& operator=(const BinTree<T>& source);
// destructor
~BinTree() { free(root); }
bool isEmpty();
void add(T item);
void printAll() { print(root); }
bool readFile(std::string fileName);
bool writeFile(std::string fileName);
private:
BinNode<T>* root;
void free(BinNode<T>* ptr);
void print(BinNode<T>* ptr);
void copyTree(BinNode<T>* ptr);
void writeFile(BinNode<T>* ptr, std::ofstream outFile);
};
#include "BinTree.template"
#endif
BinTree.template:
#include "BinTree.h"
// BinTree.template definition
template <typename T>
BinTree<T>::BinTree() {
root = nullptr;
}
template<typename T>
BinTree<T>::BinTree(const BinTree<T>& source) {
this->root = nullptr;
copyTree(source->root);
}
template<typename T>
BinTree<T>& BinTree<T>::operator=(const BinTree<T>& source) {
if (this == &source)
return *this;
free(this->root);
this->root = nullptr;
copyTree(source->root);
}
template<typename T>
bool BinTree<T>::isEmpty() {
return (root == nullptr); // true - empty, false - not empty
}
template<typename T>
void BinTree<T>::add(T item) {
BinNode<T>* temp = new BinNode<T>(item); // other constructor
if (isEmpty())
root = temp;
else {
BinNode<T>* ptr = root;
while (ptr != nullptr) {
if (temp->data <= ptr->data) { // Left side
if (ptr->left == nullptr) { // Left spot open
ptr->left = temp; // Add it
ptr = nullptr; // End Loop
}
else { // Left spot not open
ptr = ptr->left;
}
}
else { // Right side
if (ptr->right == nullptr) { // Right open
ptr->right = temp; // Add it
ptr = nullptr; // End Loop
}
else {
ptr = ptr->right;
}
}
}
}
}
template<typename T>
bool BinTree<T>::readFile(std::string fileName) {
std::ifstream inFS;
inFS.open(fileName);
T temp;
if (!inFS.is_open()) {
std::cout << "Error opening " << fileName << std::endl;
return false;
}
while (!inFS.eof()) {
getline(inFS, temp);
add(temp);
}
inFS.close();
return true;
}
template<typename T>
bool BinTree<T>::writeFile(std::string fileName) {
std::ofstream outFS;
outFS.open(fileName);
if (!outFS.is_open()) {
std::cout << "Error writing to " << fileName << std::endl;
return false;
}
writeFile(root, outFS); // <------ COMPILER ERROR ON THIS LINE ****
outFS.close();
return true;
}
template<typename T>
void BinTree<T>::writeFile(BinNode<T>* ptr, std::ofstream outFile) {
if (ptr != nullptr) {
writeFile(ptr->left, outFile);
outFile << ptr->data << std::endl;
writeFile(ptr->right, outFile);
}
}
template<typename T>
void BinTree<T>::free(BinNode<T>* ptr) {
if (ptr != nullptr) {
free(ptr->left);
free(ptr->right);
delete ptr;
}
}
template<typename T>
void BinTree<T>::print(BinNode<T>* ptr) {
if (ptr != nullptr) {
print(ptr->left);
std::cout << ptr->data << std::endl;
print(ptr->right);
}
}
template<typename T>
void BinTree<T>::copyTree(BinNode<T>* ptr) {
if (ptr != nullptr) {
add(ptr->data);
copyTree(ptr->left);
copyTree(ptr->right);
}
}
BinNode.h:
#ifndef BINNODE_H
#define BINNODE_H
template <typename T>
class BinTree;
template <typename T>
class BinNode {
friend class BinTree<T>;
public:
BinNode() : left(nullptr), right(nullptr), data(T()) {} // Default constructor
BinNode(T item) : left(nullptr), right(nullptr), data(item) {}
private:
BinNode<T>* left;
BinNode<T>* right;
T data;
};
#endif
CodePudding user response:
Your function gets the std::ofstream
by value, but the copy constructor is deleted:
You need to pass the stream by reference instead:
template<typename T>
void BinTree<T>::writeFile(BinNode<T>* ptr, std::ofstream &outFile) {
// ...
}