Re: passing function object pointer to for_each argument
On 27 Sep., 12:09, hongseok.y...@gmail.com wrote:
class test_a
{
public:
virtual void operator()(int i)
{
_test();
}
virtual void _test()
{
cout << "test_a::_test()" << endl;
}
};
Some design issues:
1) Use the non-virtual interface (NVI) pattern, that is make your
operator()
non-virtual (You already realize virtual behaviour via delegation to
_test()).
Of-course, this is *not* the reason of your actual problem.
2) Make operator() const (and _test as well). (Also not the root of
your
problem)
class test_b : public test_a
{
public:
virtual void _test()
{
cout << "test_b::_test()" << endl;
}
};
int main()
{
test_a* a = new test_a;
test_a* b = new test_b;
vector<int> v;
v.push_back(1);
for_each(v.begin(), v.end(), *a);
for_each(v.begin(), v.end(), *b);
delete a;
delete b;
return 0;
}
Result :
test_a::_test()
test_a::_test()
------------------------------------------------
Why the result is not...
test_a::_test()
test_b::_test()
???
tell me why and how can I fix it?
Your problem is "slicing" and it occurs, because all
algorithms expecting a function do take these by
value (There is only one exception: random_shuffle, because
the random number generator usually contains state).
Now the static type of both *a and *b is indeed
test_a and therefore the copy of that is an test_a
instance (inside for_each) in both cases.
The fix is easy: *Always* use functors, which behave like
value types. E.g. you can do that by wrapping a test_a
pointer inside a non-virtual functor (Copying the pointer
does not result in slicing ;-)):
class test
{
public:
explicit test(test_a& a) : pa(&a) {}
void operator()(int i) const
{
return (*pa)(i);
}
private:
test_a* pa;
};
and replace the for_each calls by:
for_each(v.begin(), v.end(), test(*a));
for_each(v.begin(), v.end(), test(*b));
Greetings from Bremen,
Daniel Kr|gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]