const member function problems

Hi, so the problem is that I was trying to make my Tnode class and one of the functions is supposed to find node with given string value and return pointer to that Tnode.

As I see it this operation is not changing the node itself so I tried to define it const but I couldn't. I had to write 2 different functions 1 for const version and one for non const

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
struct Tnode {

	std::string word;
	int count;

	Tnode* left;
	Tnode* right;
	Tnode* parent;

	~Tnode() { delete left; delete right; delete parent; }

	void add_node(std::string, int);
	

        //this alone didnt work
        //Tnode* find(const std::string&) const;          

        const Tnode* find(const std::string&) const;    //const version
	Tnode* find(const std::string&);                //non const version
};


Why I was unable to just define one function for both cases
Tnode* find(const std::string&) const;
As far as I remember if I have just this one last function, in case of const object I would return const Tnode* but if object is not const than just Tnode*
I'm using Visual Studio 2015

EDIT :
Ok interesting news. I was not even able to write definition of
Tnode* find(const std::string& str)
I just want to create find version for both const and non const objects. What am I doing wrong?

If I write just one function like this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Tnode* Tnode::find(const std::string& str) const {

	if (word == str) return this;
	else if (str > word) {
		//look in right node if it exists
		if (right)
			right->find(str);
		else
			return nullptr;
	}
	else if (str < word) {
		//look in right node if it exists
		if (left)
			left->find(str);
		else
			return nullptr;
	}
}

I cant return this
Last edited on
As I see it this operation is not changing the node itself so I tried to define it const but I couldn't.
Why not?


By the way: You should introduce a constructor that sets count and the nodes to 0.
If I write just one function like this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Tnode* Tnode::find(const std::string& str) const {

	if (word == str) return this;
	else if (str > word) {
		//look in right node if it exists
		if (right)
			right->find(str);
		else
			return nullptr;
	}
	else if (str < word) {
		//look in right node if it exists
		if (left)
			left->find(str);
		else
			return nullptr;
	}
}

I cant return this

return value type does not match the function type


Yea I should probably make constructor, its just in the start it was supposed to just store some data but now I kind of felt like upgrading it - v 2.0 :D. Haven't done it yet


EDIT : ok so here is the full version so it can be fast opened on cpp.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <string>

struct Tnode {
	std::string word;
	int count;

	Tnode* left;
	Tnode* right;
	Tnode* parent;

	~Tnode() { delete left; delete right; delete parent; }

	void add_node(std::string, int);
	Tnode* find(const std::string&) const;  
};

Tnode* Tnode::find(const std::string& str) const {
    
	if (word == str) return this;       // Im not allowed to return this here!!!
	else if (str > word) {
		//look in right node if it exists
		if (right)
			return right->find(str);
		else
			return nullptr;
	}
	else if(str < word){
		//look in left node if it exists
		if (left)
			return left->find(str);
		else
			return nullptr;
	}

}

int main(){
    return 0;    
}


19:26: error: invalid conversion from 'const Tnode*' to 'Tnode*' [-fpermissive]
Last edited on
What am I doing wrong?
You're not doing anything wrong. It's a good style to return const when the function is const. Why creating a const function if it does the same as a non const?

But you can avoid code duplication:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
template<typename node_type>
node_type * Tnode_find(node_type *node_ptr, const std::string& str) {

	if (node_ptr->word == str) return node_ptr;
	else if (str > node_ptr->word) {
		//look in right node if it exists
		if (node_ptr->right)
			return node_ptr->right->find(str); // Note: return
		else
			return nullptr;
	}
	else if (str < node_ptr->word) {
		//look in right node if it exists
		if (node_ptr->left)
			return node_ptr->left->find(str); // Note: return
		else
			return nullptr;
	}
}

const Tnode* Tnode::find(const std::string& str) const {
  return Tnode_find(this, str);
}

Tnode* Tnode::find(const std::string& str) {
  return Tnode_find(this, str);
}
This is looking good man and thanks a lot. I don't want to be unthankful but I still really want to know why my previous version didnt work - this one

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <string>

struct Tnode {
	std::string word;
	int count;

	Tnode* left;
	Tnode* right;
	Tnode* parent;

	~Tnode() { delete left; delete right; delete parent; }

	void add_node(std::string, int);
	Tnode* find(const std::string&) const;  
};

Tnode* Tnode::find(const std::string& str) const {
    
	if (word == str) return this;       // Im not allowed to return this here!!!
	else if (str > word) {
		//look in right node if it exists
		if (right)
			return right->find(str);
		else
			return nullptr;
	}
	else if(str < word){
		//look in left node if it exists
		if (left)
			return left->find(str);
		else
			return nullptr;
	}

}

int main(){
    return 0;    
}


EDIT :
Im having a question about your previous example
Isnt there some kind of infinite loop if in the template find version you are calling Tnode -> find() but Tnode's find() is calling template version of find. They are calling each other all the time as I see it =/
Last edited on
The const at the end of the function expresses exactly that: this is const. See:

http://en.cppreference.com/w/cpp/language/member_functions
http://stackoverflow.com/questions/15413037/what-does-cv-unqualified-mean-in-c

cppreference wrote:
In the body of a cv-qualified function, the this pointer is cv-qualified, e.g. in a const member function, only other const member functions may be called normally.
Tnx for the links man. But I read in Stroustrups book that const member functions can be called on both - const and non const objcts. const just means that operation is not going to modify the object. So If I would call this function on const object according to book const Tnode* should be returned but if object wasn't const than Tnode* instead.
Is the above information I wrote is false?

If it is true than below doesn't make much sense anyway
1
2
3
Tnode* Tnode::find(const std::string& str) {
	return this;      //works like a charm but cant call on const objects
}

1
2
3
Tnode* Tnode::find(const std::string& str) const {
	return this;      //doesn't compile
}
Isnt there some kind of infinite loop if in the template find version you are calling Tnode -> find() but Tnode's find() is calling template version of find.
It would be infinite only when the passed pointer would be the same at a point.


Is the above information I wrote is false?
As far as I undstand it you're right.

If it is true than below doesn't make much sense anyway
Correct. const is there for a reason.
but than why is
1
2
3
Tnode* Tnode::find(const std::string& str) const {
	return this;      //doesn't compile
}

not compiling. What am I missing :D

EDIT : ok I saw that if return type wouldnt be pointer or reference than this const function would work for both const and non const

Ohh man sry for wasting so much of your time.
The very 1st problem when I wasnt able to write definition for Tnode* Tnode::find(const std::string& str) was becauseI didnt write Tnode:: before find. But still i learned some good things from this so thank you very much man for sticking to this post :)
Last edited on
Topic archived. No new replies allowed.