Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Not understanding C++ type mismatch: const Foo* to Foo* const&

Having this set of objects and statements:

QSet<Foo*> set;
iterator QSet::insert(const T & value)    //type of the function I want to call
const Foo * get() const                   //type of the function I use to get the argument

set.insert(get());                        //the line showing up as error

I get the error "no known conversion for argument 1 from 'const Foo*' to 'Foo* const&". I guess I have trouble reading these types because I have no idea what I should do to make this work.

From what I've read, the const keyword applies to the type to its left with the exception of a top-level const which can be written to the left of the type it applies to. My guess would be that I have to convert get() to a reference but I'm unsure how to do that.

like image 491
Balz Guenat Avatar asked May 05 '15 02:05

Balz Guenat


2 Answers

There seem to be a couple of misunderstandings here (both by the questioner and by some answers).

First, you said "My guess would be that I have to convert get() to a reference but I'm unsure how to do that". Let's try clearing this up:

1) "I have to convert get() to a reference" -- Actually, you don't!

iterator QSet::insert(const T & value) does indeed take a reference. But it's a reference to type T. So the question is, "what is type T"?

In this case, T=Foo *. So insert, in this instance of the template, is actually:

iterator QSet::insert(Foo * const & value) -- read it from right to left: insert takes a reference to a constant pointer to a Foo.

2) "I'm unsure how to do that [convert a pointer to a reference]" -- while you don't have to do it here, in general you do this by de-referencing the result of get. For example: *(get()).

Second, the compiler error. The error arises because there is a conflict:

a) get() returns a const Foo *

b) but set stores a Foo* -- NOT a const Foo *, so insert only accepts a changeable Foo

So you can't store a constant pointer inside your QSet<Foo*>. This makes sense because you can use set to access and change the Foos inside it, which you promise not to do with a const Foo.

This reference should be helpful:

https://isocpp.org/wiki/faq/const-correctness

You may also think whether you can just use a QSet<Foo> instead of a QSet<Foo*>. In the former case, things will probably behave how you expect.

like image 71
Corey Avatar answered Sep 20 '22 13:09

Corey


You are trying to take a const Foo * and insert it into a QSet<Foo *>, but the compiler won't automatically convert a const Foo * to a plain Foo * in order to do so.

like image 22
Greg Hewgill Avatar answered Sep 17 '22 13:09

Greg Hewgill