Is it const correct to pass const to a function that accepts a const pointer?


Steve Lorimer

I have a class template Foowith the following member functions :

bool contains(const T& item) const

I have instantiated this with a pointer type: Foo<Bar*>, leading me to expect that the member function will now have the following signature:

bool contains(const Bar*& item) const

In the const Barmember function, I try to pass thisto Foo<Bar*>::contains:

bool Bar::func(const Foo<Bar*>& foo) const
{
    return foo.contains(this);
}

Compilation fails with the following error:

error: invalid conversion from " const Bar*" to " Bar*"

question:

  • Why is my const T&parameter not const correct?
  • Foo<T>::contains(...) constWhich signature is allowed to thiscompile with?

Complete example:

#include <vector>
#include <algorithm>

template<typename T>
struct Foo
{
    bool contains(const T& item) const
    {
        return false;
    }
};

struct Bar
{
    bool func(const Foo<Bar*>& foo) const
    {
        return foo.contains(this);
    }
};

Error output:

scratch/main.cpp:17:33: error: invalid conversion from ‘const Bar*’ to ‘Bar*’ [-fpermissive]
         return foo.contains(this);
                                 ^
scratch/main.cpp:7:10: note: initializing argument 1 of ‘bool Foo<T>::contains(const T&) const [with T = Bar*]’
     bool contains(const T& item) const
Makovic

I have instantiated this with a pointer type: Foo<Bar*>, leading me to expect that the member function will now have the following signature:

bool contains(const Bar*& item) const

That's the problem. At that time T = Bar*, the expression

bool contains(const T& item) const

will actually compile to

bool contains(Bar * const & item) const

That is, a Bar that points to a constant pointer. It makes sense to think about it: you want T to be const, and then you want a reference to it.

If you want to apply const in the usual "predetermined" way (although this may surprise experienced C++ programmers), you can declare containers and member functions in the following way:

template <class T>
class Container {
public:
    using const_bare_type = typename std::conditional<
        std::is_pointer<T>::value,
        typename std::remove_pointer<T>::type const*,
        const T>::type;

    bool contains(const const_bare_type& item);
};

Related


Pass const pointer to const by reference in function

Jon I'm playing with arrays and passing pointers by reference functions. Take the following code as an example: #include<iostream> void test_fn(const int* const &i){ std::cout<<*i<<std::endl; } int main(){ int arr_1[5] {1, 3, 6, 4, 5}; int *int_p

Pass const pointer to const by reference in function

Jon I'm playing with arrays and passing pointers by reference functions. Take the following code as an example: #include<iostream> void test_fn(const int* const &i){ std::cout<<*i<<std::endl; } int main(){ int arr_1[5] {1, 3, 6, 4, 5}; int *int_p

Pass const pointer to const by reference in function

Jon I'm playing with arrays and passing pointers by reference functions. Take the following code as an example: #include<iostream> void test_fn(const int* const &i){ std::cout<<*i<<std::endl; } int main(){ int arr_1[5] {1, 3, 6, 4, 5}; int *int_p

Pass const pointer to const by reference in function

Jon I'm playing with arrays and passing pointers by reference functions. Take the following code as an example: #include<iostream> void test_fn(const int* const &i){ std::cout<<*i<<std::endl; } int main(){ int arr_1[5] {1, 3, 6, 4, 5}; int *int_p

Pass pointer to const ref function

Dean Why does the following work? #include <iostream> using namespace std; class PolyLine { public: PolyLine() = default; PolyLine(PolyLine * ptr) { std::cout << "Ctor called" << std::endl; } }; void function(const PolyLine& pt) { } int main() {

cannot pass 'const pointer const' to const ref

Thomas B. Suppose you have a set of pointers (yes...): std::set<SomeType*> myTypeContainer; Then suppose you want to search this collection from a const method of SomeType: bool SomeType::IsContainered() const { return myTypeContainer.find(this) != myType

cannot pass 'const pointer const' to const ref

Thomas B. Suppose you have a set of pointers (yes...): std::set<SomeType*> myTypeContainer; Then suppose you want to search this collection from a const method of SomeType: bool SomeType::IsContainered() const { return myTypeContainer.find(this) != myType

cannot pass 'const pointer const' to const ref

Thomas B. Suppose you have a set of pointers (yes...): std::set<SomeType*> myTypeContainer; Then suppose you want to search this collection from a const method of SomeType: bool SomeType::IsContainered() const { return myTypeContainer.find(this) != myType

Assign function to function pointer, const parameter correct?

edwardlam0328 I'm currently learning the basics of C++ and OOP at my university. I'm not 100% sure how it works when assigning a function to a function pointer. I came across the following code: void mystery7(int a, const double b) { cout << "mystery7" << endl

Assign function to function pointer, const parameter correct?

edwardlam0328 I'm currently learning the basics of C++ and OOP at my university. I'm not 100% sure how it works when assigning a function to a function pointer. I came across the following code: void mystery7(int a, const double b) { cout << "mystery7" << endl

const correct array pointer?

Lundin It has been argued that in modern C we should always pass arrays to functions via array pointers due to their strong typing. example: void func (size_t n, int (*arr)[n]); ... int array [3]; func(3, &array); It sounds like this might be a good idea to

const correct array pointer?

Lundin It has been argued that in modern C we should always pass arrays to functions via array pointers due to their strong typing. example: void func (size_t n, int (*arr)[n]); ... int array [3]; func(3, &array); It sounds like this might be a good idea to

const correct array pointer?

Lundin It has been argued that in modern C we should always pass arrays to functions via array pointers due to their strong typing. example: void func (size_t n, int (*arr)[n]); ... int array [3]; func(3, &array); It sounds like this might be a good idea to

const correct array pointer?

Lundin It has been argued that in modern C we should always pass arrays to functions via array pointers due to their strong typing. example: void func (size_t n, int (*arr)[n]); ... int array [3]; func(3, &array); It sounds like this might be a good idea to

const correct array pointer?

Lundin It has been argued that in modern C we should always pass arrays to functions via array pointers due to their strong typing. example: void func (size_t n, int (*arr)[n]); ... int array [3]; func(3, &array); It sounds like this might be a good idea to

Pass pointer by const reference

csguy Isn't passing pointers by const reference for optimization? predecessor. bool testHelper(const TreeNode*& p, const TreeNode*& q) { return false; } TreeNode* test(TreeNode* root, TreeNode* p, TreeNode* q) { recursiveHelper(p, q); } mistake: Line

pass a const pointer

catch_0x16 When using 3D/2D graphics libraries, I often find myself passing a pointer to the render window to each drawable class that draws itself onto the canvas. However, every time I do this, I worry that by passing a pointer to the render window, the obje

pointer to const (or pointer to const)

Wengers I have the following code: #include <iostream> int main(){ int v1 = 20; int *p1 = &v1; int **p2 = &p1; return 0; } What I'm trying to do here is point one pointer to another and it works fine in this case. I make p1 point to a cons

pointer to const in function call

Acetate I have an array of integers int foo[3]and I want to pass it to another function. I want to accomplish two things: pass by reference Set it to constant as it should not be modified. The function I define is: void print_foo(const int(*const foo)[3]) {

pointer to const as function parameter

Cerno I have the following basic code: base code int main() { int i = 1; const int* p = &i; int* q = &i; test_ptr(p); test_ptr(q); } Can anyone explain why the first and third examples work with the above basic code, but not the second? Example im

pointer to const as function parameter

Cerno I have the following basic code: base code int main() { int i = 1; const int* p = &i; int* q = &i; test_ptr(p); test_ptr(q); } Can anyone explain why the first and third examples work with the above basic code, but not the second? Example im

pointer to const as function parameter

Cerno I have the following basic code: base code int main() { int i = 1; const int* p = &i; int* q = &i; test_ptr(p); test_ptr(q); } Can anyone explain why the first and third examples work with the above basic code, but not the second? Example im

pointer to const in function call

Acetate I have an array of integers int foo[3]and I want to pass it to another function. I want to accomplish two things: pass by reference Set it to constant as it should not be modified. The function I define is: void print_foo(const int(*const foo)[3]) {

pointer to const as function parameter

Cerno I have the following basic code: base code int main() { int i = 1; const int* p = &i; int* q = &i; test_ptr(p); test_ptr(q); } Can anyone explain why the first and third examples work with the above basic code, but not the second? Example im

pointer to const as function parameter

Cerno I have the following basic code: base code int main() { int i = 1; const int* p = &i; int* q = &i; test_ptr(p); test_ptr(q); } Can anyone explain why the first and third examples work with the above basic code, but not the second? Example im

pointer to const as function parameter

Cerno I have the following basic code: base code int main() { int i = 1; const int* p = &i; int* q = &i; test_ptr(p); test_ptr(q); } Can anyone explain why the first and third examples work with the above basic code, but not the second? Example im

pointer to const as function parameter

Cerno I have the following basic code: base code int main() { int i = 1; const int* p = &i; int* q = &i; test_ptr(p); test_ptr(q); } Can anyone explain why the first and third examples work with the above basic code, but not the second? Example im