Assume I have this class (inherited from std::Vector, it's just an example)
#include <vector>
using namespace std;
template <class T>
class C : public vector<T> {
// I don't want to use static keyword
void transformation(T i) {
i *= 100;
}
public:
void method() {
for_each(this->begin(), this->end(), transformation);
}
};
int main() {
C<double> c;
for (int i=-3; i<4; ++i) {
c.push_back(i);
}
c.method();
}
How do I call for_each using class method inside class itself? I know I can use static keyword, but what is there any other way how to use a function object without using static?
I get this error message while compiling:
for_each.cc:21:55: error: cannot convert
‘C::transformation’ from type ‘void (C::)(double)’
to type ‘void (C::*)(double)’ for_each(this->begin(),
this->end(), transformation);
I think I need to add .*
or ->*
somewhere but I can't find out where and why.
C++11 bind solution:
std::for_each(this->begin(), this->end(),
std::bind(&C::transformation, this, std::placeholders::_1));
C++11 lambda solution:
std::for_each(this->begin(), this->end(),
[this] (T& i) { transformation(i); });
C++14 generic lambda solution:
std::for_each(this->begin(), this->end(),
[this] (auto&& i) { transformation(std::forward<decltype(i)>(i)); });
C++98 bind1st+mem_fun solution:
std::for_each(this->begin(), this->end(),
std::bind1st(std::mem_fun(&C::transformation), this));
Note: this->begin()
and this->end()
calls are qualified with this->
only because in the OP's code they are member functions of a templated base class. As such, those names are primirarily searched in a global namespace. Any other occurrence of this
is mandatory.
For starters, don't inherit from the standard containers, they are not designed to be inherited (no virtual destructors etc.).
Secondly, and regarding your problem, it's because a pointer to a member function is not the same as a pointer to a function. The reason is that member function has a hidden first parameter which becomes the this
pointer in the function. The simplest way to solve it is to make the function static
.
Another solution is to use the std::bind
function that came with C++11:
for_each(this->begin(), this->end(),
std::bind(&C::transformation, this, std::placeholders::_1));
If you don't have C++11 (even though you tagged your question as such), then you probably could get something working with std::mem_fun
or std::bind1st
.
You need to bind the this
pointer:
public:
void method()
{
for_each(this->begin(), this->end(), bind(&C::transformation, this, placeholders::_1));
}