Search code examples
c++pointersconstantsconst-casttemplate-classes

conversion between 2 types with different const qualifiers


This is a short example of the code I want to use:

template <class T>
class B
{
public :
    bool func1(const T& t)
    {
        // do something
    }
};


class A
{
    B<int*> b;
public:
    void func2(const int* a)
    {
        b.func1(a);
    }
};

I'm getting this error :

error C2664: 'B::func1' : cannot convert parameter 1 from 'const int *' to 'int *const &'

is a way to solve this without changing the functions declarations and without using const_cast?

Edit:

some information behind the problem

  1. B is actually a container class I wrote (lets say a list)

  2. A is a class using that list

  3. func1 is a function that need to find if an element is in the list or not

  4. func2 is a function that recieves an element to remove from the list


Solution

  • If you want the reference to the const pointer, then try this:

    B<const int*> b;
    

    If you know for sure that what you are passing in is not originally a const int * (that is, you originally have an int * and it turned into a const int * somewhere along the way), then you can do this:

    b.func1(const_cast<int *>(a));
    

    Note that this can easily lead to undefined behavior if the precondition I mentioned is not met. And it's confusing because the user of a function would not expect the function to change what is pointed to by the pointer. Better to pass in an int * from the get-go:

    void func2(int* a) 
    {
        b.func1(a);
    }
    

    Based on your latest comment, I think this is what you want:

    template <class T>
    class B
    {
        typedef typename std::remove_pointer<T>::type base_type;
        typedef typename std::add_const<base_type>::type const_base_type;
        typedef typename std::add_pointer<const_base_type>::type pointer_const_base_type;
    public :
        void func1(const pointer_const_base_type& t)
        {
            std::cout << t << std::endl;
        }
    };
    

    Given T = base_type *, I laboriously build up pointer_const_base_type = const base_type *. Now func1 takes a reference to that const base_type *. Note this assumes that T is a pointer to something; you'll have to fiddle with it more to work for non-pointers.