Adam
Adam

Reputation: 464

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

Upvotes: 3

Views: 130

Answers (2)

R Sahu
R Sahu

Reputation: 206607

When int* is used to instantiate B, the function

void func1(const T& t) {}

is equivalent to:

void func1(int* const& t) {}

A parameter of type const int* is not compatible with int* const&.

You need to rethink your functions a bit.

Update

Use of B<int> instead of B<int*> in A might be what you are looking for.

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

Upvotes: 6

Claudiu
Claudiu

Reputation: 229361

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.

Upvotes: 3

Related Questions