No Match for 'operator' error in C++ - c++

#include <iostream>
#include <string>
#include <cstdlib>
#include <cassert>
#include <ctime>
#include <map>
using namespace std;
struct SBLnode {
string name;
SBLnode *next;
SBLnode * left, * right;
};
struct Queue {
SBLnode * first, * last;
};
typedef SBLnode* BST;
struct SBL {
Queue q;
BST root;
};
void SBL_init (SBL& sbl) {
sbl = NULL;
}
I keep getting the following error in GCC when compiling...
error: no match for ‘operator=’ (operand types are ‘SBL’ and ‘long int’)
sbl = NULL;
^
This error basically is for the line sbl = NULL and it would be great if someone could explain to me exactly what that error actually means.

It can't find the operator= for SBL &SBL::operator=(const long int &rhs). There is a better practice. One option is to use a pointer and set it to NULL. NULL evaluates to 0. There is no operator which assigns an int intriniscally to your SBL struct object.
Or define a const static instance of the struct with the initial values and then simply assign this value to your variable whenever you want to reset it.
For example:
static const struct SBL EmptyStruct;
This uses static initialization to set the initial values.
Then, in init you can write:
sbl = EmptyStruct;
Note: Have to compile with -fpermissive in gcc or set EmptyStruct = { }. The reason why you have to set -fpermissive is listed here for GCC 4.6. GCC 4.4 needs EmptyStruct = { }.
Here is your program running. Initially it prints "initial" twice and on the third time, it prints empty string. Meaning, it was set to nothing by the assignment in the init function.
int main()
{
struct SBLnode initial;
initial.name = "initial";
struct Queue q;
q.first = &initial;
cout << q.first->name << endl;
struct SBL testInit;
testInit.q = q;
SBL_init(testInit);
cout << testInit.q.first->name << endl;
return 0;
}
http://ideone.com/Ecm6I9

void SBL_init (SBL& sbl) {
sbl = NULL;
}
Others have already pointed out why that line doesn't compile. Perhaps I can suggest an alternative solution. Instead of providing an init function, why not give all of your structures constructors like so? Is there some reason that you can't provide those? The operator= and copy constructor don't need to be defined if shallow copying of pointers is what you want. Since nodes typically need to be moved around I'm guessing that a shallow copy is fine. You can certainly use the nullptr if using c++ 11 rather than 0. I'm not a big fan of the NULL macro and opinions often vary with regards to NULL.
struct SBL {
SBL() : root(0) {}
Queue q;
BST root;
};
struct Queue {
Queue() : first(0), last(0) {}
SBLnode * first, * last;
};

NULL is a macro which expands to the integer literal 0. There is no intrinsic or user-defined operator which can assign an integer to an object of type SBL.
It looks like you are treating sbl as a pointer; but it is not a pointer, it is a reference.
You probably wanted to write this instead:
void SBL_init (SBL& sbl) {
sbl.root = NULL;
}
This initializes sbl by nulling out its member pointers.
As others have commented, nullptr is preferred in C++11:
void SBL_init (SBL& sbl) {
sbl.root = nullptr;
}

This error means that operator= , which is a function, is not defined in struct SBL. It is required when you write
sbl = NULL;
Solution:
provide SBL& operator=( const long int& i); in struct SBL.
In fact I think that you would like something alike SBL& operator=( BST b):
struct SBL {
Queue q;
BST root;
SBL& operator=( BST b) {
root = b;
return *this;
}
};

It is trying to find an assignment operator that has the form
SBL &SBL::operator=(const long int &rhs):#
and cannot find one.
I guess you were thinking about the pointers.

Related

Difference Between "struct Obj* obj" and "Obj* obj"

struct Element{
Element() {}
int data = NULL;
struct Element* right, *left;
};
or
struct Element{
Element() {}
int data = NULL;
Element* right, *left;
};
I was working with binary trees and I was looking up on an example. In the example, Element* right was struct Element* right. What are the differences between these and which one would be better for writing data structures?
I was looking up from this website:
https://www.geeksforgeeks.org/binary-tree-set-1-introduction/
In C, struct keyword must be used for declaring structure variables, but it is optional(in most cases) in C++.
Consider the following examples:
struct Foo
{
int data;
Foo* temp; // Error in C, struct must be there. Works in C++
};
int main()
{
Foo a; // Error in C, struct must be there. Works in C++
return 0;
}
Example 2
struct Foo
{
int data;
struct Foo* temp; // Works in both C and C++
};
int main()
{
struct Foo a; // Works in both C and C++
return 0;
}
In the above examples, temp is a data member that is a pointer to non-const Foo.
Additionally, i would recommend using some good C++ book to learn C++.
In C++, defining a class also defines a type with the same name so using struct Element or just Element means the same thing.
// The typedef below is not needed in C++ but in C to not have to use "struct Element":
typedef struct Element Element;
struct Element {
Element* prev;
Element* next;
};
You rarely have to use struct Element (other than in the definition) in C++.
There is however one situation where you do need it and that is when you need to disambiguate between a type and a function with the same name:
struct Element {};
void Element() {}
int main() {
Element x; // error, "struct Element" needed
}

C++ How may I return an array class member of a nested class?

This is not a real question, since I've already solved the problem myself, but I still need some clarifications about the mechanism behind assigning an array's address to a pointer of the same type when the array is a class member of a nested class.
The following code is fully functioning, although it may lack some error_check. It is only meant to show how I made my (real) program work.
HEADER (linkedList)
class linkedList
{
public:
linkedList();
~linkedList();
int* getArray();
void forward();
private:
class listNode
{
public:
listNode();
~listNode();
friend class linkedList;
private:
int array[3];
listNode* next;
};
listNode *first;
listNode *current;
};
CPP (linkedList)
linkedList::linkedList()
{
first = new listNode;
current = first;
}
//~~~~~~~~~~~~
linkedList::~linkedList()
{
delete first;
first = 0;
current = 0;
}
//~~~~~~~~~~~~
int* linkedList::getArray()
{
if (current)
{
return &(current->array[0]);
}
}
//~~~~~~~~~~~~
void linkedList::forward()
{
if (current->next)
{
current = current->next;
}
}
//-------------------------
//-------------------------
//-------------------------
linkedList::listNode::listNode()
{
next = 0;
for (int i = 0; i < 3; i++){array[i]=((i+1)*3);}
}
//~~~~~~~~~~~~
linkedList::listNode::~listNode()
{
}
CPP (main)
#include <iostream>
#include "linked_list.h"
using namespace std;
int main()
{
linkedList list;
int *myArray;
myArray = list.getArray();
for (int i = 0; i < 3; i++){cout << myArray[i] << " ";}/**/cout << "\n\n";
return 0;
}
The real program is meant to move through a linked list made of nodes which contain 3 integer values in an array of int type, retrieve the three values and use them as parameters for some other functions.
Now, to do so I have to return the address to the first element of the array contained in the node through an accessor.
Apparently, the only way to do it is by returning the reference to the first element of the array in the node to which the linkedList's member variable current points to:
return &(current->array[0]);.
Why?
I've got to this solution through trial and error with very little knowlegde of the reasons that brought me to build this expression as it is.
Usually, when you want to assign the address of an array to a pointer, you just do so:
int main()
{
int array[3];
int* pArray;
pArray = array;
}
And that's it, because the name of the array itself is enough to retrieve the address of its first element.
The exact same result can be achieved by doing this (tested):
int main()
{
int array[3];
int* pArray;
pArray = &(array[0]);
}
Both methods are also valid when the accessor returns the address from a member variable of its own class.
But why, when accessing the member variable of a nested class, I'm forced to use the second method?
What are the logic stages that make it the only viable method?
But why, when accessing the member variable of a nested class, I'm forced to use the second method?
You aren't:
return current->array;
and
return &(current->array[0]);
Both do the same thing when the return type is int*. You aren't forced to use the second way.
Also, there's a bug in getArray. You don't return anything if current is null.
To be pedantic...
Apparently, the only way to do it is by returning the reference to the first element of the array in the node to which the linkedList's member variable current points to:
return &(current->array[0]);.
You're returning the address i.e. a pointer. Reference means something else.

How can I new and initialize a struct in C++?

In C, we actually do
struct node *p = (node*)malloc(sizeof(node)); // casting is not necessary
p->a = 0; // first element
p->b = NULL; // second element
to dynamically allocate spaces in the memory, but how can I do this in C++ way?
Is the line below a correct guess?
node *p = new node {0, NULL};
Yes, you are correct.
Assuming node is an aggregate, your C++ version is right (modulo NULL rather than nullptr).
That being said, if these initial values are "defaults", you would conventionally write a default constructor to initialise those members for you automatically:
struct node
{
int a;
node* b;
node() : a(0), b(nullptr) {}
};
Then you'd just write:
node* p = new node;
Or, better:
auto p = std::make_unique<node>();
Or, better yet:
node n;
Default-construction has some consequences though. You may not want any constructors.
In C++ you would avoid a naked new and either create a shared/unique pointer with std::make_shared/std::make_unique in C++11/14 or encapsulate the allocation in a handle-class following the RAII idiom.
To give an example of how that would work:
class Foo {
const int i;
public:
int j;
Foo(int i) : i{i}, j{0} {}//constructor
void foo() {std::cout << i << "\n";}
};
int main() {
unique_ptr<Foo> fp = make_unique<Foo>(5);
fp->foo();
return 0;
}
In case the constructor looks a bit confusing to you, a short explanation: The colon after the constructors signature starts the initialization declaration. In this section you have to initialize const-values, but you can initialize all values there. Thus constructors, which take arguments often look like this:
Foo(ArgType1 arg1, ArgType2 arg2,...,ArgTypeN argN) :
member1(arg1), member2(arg2), ... , memberN(argN) {//empty body}
Be sure to pay attention to the rule of three/five, when writing constructors.

Changing address of a struct in C++ by ++ and -- operator

Is it possible to change the address of my current struct using the -- or ++ operator, i.e.:
mystruct* test = existing_mystruct;
test++ // instead of using: test = test->next_p;
I was trying to use this, but it seems to be const and gives me an Error: assignment to this (anachronism):
struct mystruct {
mystruct* next_p;
mystruct* prev_p;
void operatorplusplus () { this = next_p; }
void operatorminusminus() { this = prev_p; }
};
Objects have a constant address in memory while they exist.
You may copy them to a new address, however.
What you try to do is advance in a linked list. And it may be done with those operators if you overload them. But you will need to define that in a special handle class to wrap over the list nodes.
EDIT
The code for what I describe will look somewhat like this:
class mylist
{
struct mynode
{
//data
mynode* next;
mynode* prev;
} *curr;
public:
mylist& operator++() {curr = curr->next; return *this;}
};
Naturally you'd wanna do boundry checks and such, but that's the general idea.
No. this pointer is of type mystruct * const, which means its address is unchangeable.

use operators in templates in c++

I am trying to implement a List class using pointers and am trying to implement a function LOCATE(T x) where T is for the template and returns the first position of the element x if found, else returns last position + 1.
My functions code is
template<class T>
int List<T>::locate(T n) const
{
int size = end();
Node<T> * p = head_;
for (int i = 0; i < size; i++)
{
if (p->data() == n) // fails on this line
return i;
p = p->link();
}
return size; // if no match found
}
I initialise my list with T as string as
List<string> myList;
but I get an error message
'bool std::operator ==(const std::istreambuf_iterator<_Elem,_Traits> &,const std::istreambuf_iterator<_Elem,_Traits> &)' : could not deduce template argument for 'const std::istreambuf_iterator<_Elem,_Traits> &' from 'std::string
Why is the error coming up even though the '==' operator is defined for the string class?
'
The code for Node is
template<typename T>
class Node
{
public:
// Constructors
Node();
Node(T d, Node<T> * l = NULL);
//Inspectors
T data() const;
Node<T> * link() const;
// Mutators
void data(T d); // assigns new value to Node
void link(Node<T> * l); // points this Node to a different one
// Destructor
~Node();
private:
Node<T> * link_;
T data_;
};
template<typename T>
T Node<T>::data() const
{
return data_;
}
template<typename T>
Node<T>* Node<T>::link() const
{
return link_;
}
The calling code is
List<string> test;
test.add("abc");
cout << test.locate("abc") << endl;
Without getting neck-deep in your code, I notice several problems.
Firstly,
locate(T n)
should be
locate(const T& n)
This saves a possible copy of n
And to ask a stupid question, are you sure you've done:
#include <string>
Try :
if( n.compare(p->data()) == 0 )
string::compare documentation
As the comments below have noted, operator== should work. Please double check that you have
#include <string>
using std::string;
The reference to std::istreambuf_iterator is peculiar as nothing in the code you show justifies it -- can you please show us Node and whatever other code impinges on this in a minimal failing example? Trying to evince the problem from very partial code and an error message is very much like pulling teeth...!-)
This looks OK, I can't see how the std::istreambuf_iterator gets into the picture...
One thing you may want to adjust is taking const T& instead of T as in-parameters to your methods, e.g.
Node(const T& d, Node<T> * l = NULL);
void data(const T& d);
int List<T>::locate(const T& n) const { ...
What with the actual problem, there's bound to be something else going on.
Start deleting code untill it works again. Some typo or rogue macros or conflicting namespaces screw things up.
Will this compile by itself?
string data = "bla";
Node<string> p("bla");
bool b = p.data() == data;
(Every C++ programmer should make a cout << "bla" << end; typo. Very entertaining)