3

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

R Sahu
  • 204,454
  • 14
  • 159
  • 270
Adam
  • 464
  • 6
  • 16

2 Answers2

6

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);
      }
};
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Ha, it rather reminds me of stringing Christmas lights on a house for a few hours, only to realize you're done, and holding two female ends of the cord. So close, and yet so far! – CodeMouse92 Oct 13 '15 at 19:41
  • @JasonMc92, I haven't had that experience myself but I can imagine the anguish :) – R Sahu Oct 13 '15 at 19:43
  • R Sahu: first of all thanks for the help but I already understood the problem and I'm trying to figure a way to fix that without changing the functions or using const_cast – Adam Oct 13 '15 at 20:00
  • @Jinxed, your classes and functions seem contrived. Is there a real problem behind it? Can you elaborate the real problem in your post? – R Sahu Oct 13 '15 at 20:02
3

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.

Community
  • 1
  • 1
Claudiu
  • 224,032
  • 165
  • 485
  • 680
  • but if you notice parameter b in class A is B so func1 need to use int* as T and sending *a will sent int as you mentioned – Adam Oct 13 '15 at 19:35
  • @Jinxed: Do you want to take a const reference to the pointer, or do you want to take a const reference to the int itself? – Claudiu Oct 13 '15 at 19:36
  • @Jinxed: How about this one? Give the type as `const int*`. Otherwise it wants a reference to a non-const `int `*, and you can't pass in a `const int *` to that, as you found out. – Claudiu Oct 13 '15 at 19:39
  • @Claudio: I need the type to stay as int in order to change the ints later on the code – Adam Oct 13 '15 at 19:43
  • @Jinxed: Then you effectively want to const_cast away the `const` of the `const int *`, which can lead to undefined behavior if it was const to begin with. Your `func2` will have to take a regular `int *`. – Claudiu Oct 13 '15 at 19:44
  • @Jinxed: That you can never do through the pointer `a`, since the whole purpose of `const` appearing in the declaration of `a` is to forbid using it to change its target. – Ben Voigt Oct 13 '15 at 19:44
  • @Claudiu: let me add the following information 1) B is actually a container class I wrote (lets say a list) 2) A is a class using this list 3) func1 is function that need to find if element T is in the list or not 4) func 2 is a function that recieves element I want to remove from the list saying that, isnt the parameter a in func2 has to be a const? because I need to declare I'm not changing it – Adam Oct 13 '15 at 19:53
  • @Jinxed: Ah ok, I think I understand. Check out my latest edit. You have to change `func1`'s declaration because it really takes something other than what it's written as right now. – Claudiu Oct 13 '15 at 20:00