Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pointer to deque<int>::push_back

#include <iostream>
#include <deque>

using namespace std;
main()
{
    typedef void (deque<int>::*func_ptr)(int);
    func_ptr fptr = &deque<int>::push_back;
}

Im trying to get pointer to this function but I get a compilation error

error: cannot convert ‘void (std::deque<int>::*)(const value_type&) {aka void (std::deque<int>::*)(const int&)}’ to ‘func_ptr {aka void (std::deque<int>::*)(int)}’ in initialization
     func_ptr fptr = &deque<int>::push_back;

I want to do this so that I can get pointer to different member functions on the basis of different conditions.

I referred this link.

like image 537
harmands Avatar asked Dec 06 '16 13:12

harmands


2 Answers

As said in the accepted answer, the problem is that the type signature is different -- for a std::deque<T>, push_back only has an overload that accepts T const&, and not T directly. typedef void (deque<int>::*func_ptr)(const int &) is a perfectly concise and cromulent way to write this.

I wanted to address a C++11 way to do this -- type aliases. One may first wonder "why not use auto?" This is not possible because the function being accessed is an overloaded function, and auto does not know which of the overloads to access. Because the original question embeds the knowledge of the function type being void(int), the statement &deque<int>::push_back selects the correct overload. The problem with the simpler statement is that it bakes in knowledge of the container and the type being contained. If you want to change to a std::vector, or from int to short, you'll have to make all new types. With type aliases, we can templatize everything to avoid embedding type knowledge:

using func_ptr = void(Cont::*)(typename Cont::const_reference);

We can do something simple, as before:

func_ptr<deque<int>> fptr = &deque<int>::push_back;

...or we can refer to a container somewhere:

vector<short> container;

...looking up its type at compile time, and storing a pointer to its push_back function, all without caring what the container is:

using container_type = decltype(container);
func_ptr<container_type> fptr2 = &container_type::push_back;
like image 127
cyberbisson Avatar answered Oct 02 '22 08:10

cyberbisson


push_back() takes a const T & parameter, as the error message states:

cannot convert ‘void (std::deque::*)(const value_type&) ...

Change your type alias to:

typedef void (deque<int>::*func_ptr)(const int &);
like image 41
Sam Varshavchik Avatar answered Oct 02 '22 09:10

Sam Varshavchik