将 std::vector::push_back 与 std::mem_fun 和 std::bind1st 一起使用
我正在尝试将 std::vector
与 std::mem_fun
和 std::binder1st
一起使用,但好像不太可行,请问可以吗?
我尝试用下面的代码来举例说明。
#include <vector>
#include <functional>
#include <iostream>
using namespace std;
struct A {
int _Foo;
virtual int AFoo() { return _Foo; };
};
struct B: public A {
int BFoo(int bar) { return _Foo+bar ; };
};
struct C: public A {
int CFoo() { return --_Foo; };
};
class MyContainer
{
static const int MyArraySize = 100;
A* MyArray[MyArraySize];
public:
MyContainer() {
int half = MyArraySize / 2;
for( int i=0; i< half; ++i )
MyArray[i] = new B;
for( int i=half; i < MyArraySize; ++i )
MyArray[i] = new C;
}
template<class T, class Fn1>
int Execute( Fn1 func )
{
int count = 0;
for( int i=0; i< MyArraySize; ++i ){
T* t = dynamic_cast<T*>(MyArray[i]);
if( t )
{
func(t);
++count;
}
}
return count;
}
template<class T, class Res, class Arg>
int Execute( mem_fun1_t<Res, T, Arg> func, Arg argument )
{
return Execute<T>( binder2nd< mem_fun1_t<Res,T,Arg> >( func, argument ) );
}
template<class T>
vector<T*> GetItems() // <-- This is the problem function
{
vector<T*> ret;
Execute<T>( bind1st( mem_fun(&vector<T*>::push_back), ret ) );
return ret;
}
};
int main( int argc, char* argv[] )
{
MyContainer cont;
cont.Execute<B>( mem_fun(&B::BFoo), 10 );
cont.Execute<C>( mem_fun(&C::CFoo) );
vector<B*> v = cont.GetItems<A>(); // <-- the problem function is called here.
cout << "v.size = " << v.size() << endl;
}
我的目标是拥有一个容器类,我可以告诉它执行一个接收所选项目(“A”对象或“A”派生对象)作为参数的函数。但我没有设法将 std::vector::push_pack 与它一起使用。
I'm trying to use std::vector<T*>::push_back
with std::mem_fun
and std::binder1st
, but it doesnt seem to be feasible, can this be done?
I've tried to exemplify with the code below.
#include <vector>
#include <functional>
#include <iostream>
using namespace std;
struct A {
int _Foo;
virtual int AFoo() { return _Foo; };
};
struct B: public A {
int BFoo(int bar) { return _Foo+bar ; };
};
struct C: public A {
int CFoo() { return --_Foo; };
};
class MyContainer
{
static const int MyArraySize = 100;
A* MyArray[MyArraySize];
public:
MyContainer() {
int half = MyArraySize / 2;
for( int i=0; i< half; ++i )
MyArray[i] = new B;
for( int i=half; i < MyArraySize; ++i )
MyArray[i] = new C;
}
template<class T, class Fn1>
int Execute( Fn1 func )
{
int count = 0;
for( int i=0; i< MyArraySize; ++i ){
T* t = dynamic_cast<T*>(MyArray[i]);
if( t )
{
func(t);
++count;
}
}
return count;
}
template<class T, class Res, class Arg>
int Execute( mem_fun1_t<Res, T, Arg> func, Arg argument )
{
return Execute<T>( binder2nd< mem_fun1_t<Res,T,Arg> >( func, argument ) );
}
template<class T>
vector<T*> GetItems() // <-- This is the problem function
{
vector<T*> ret;
Execute<T>( bind1st( mem_fun(&vector<T*>::push_back), ret ) );
return ret;
}
};
int main( int argc, char* argv[] )
{
MyContainer cont;
cont.Execute<B>( mem_fun(&B::BFoo), 10 );
cont.Execute<C>( mem_fun(&C::CFoo) );
vector<B*> v = cont.GetItems<A>(); // <-- the problem function is called here.
cout << "v.size = " << v.size() << endl;
}
My goal is to have a container class to which I can tell it to execute a function receiving the selected items ('A' objects or 'A' derivate objects) as parameters. But I didn't manage to use std::vector::push_pack
with it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题是binder1st 将operator() 定义为:
而mem_fun1_t 将operator() 定义为:
问题是push_back 定义为:
所以我们最终得到的是这样的:
并且:
换句话说,对a 的引用的引用指针。 C++ 中不存在对引用的引用。我能想到解决这个问题的唯一体面的方法是使用 boost::bind 代替:
还要注意你有一个错误,并且需要传递 bind &ret 而不是仅仅 ret (因为 mem_fun 需要一个指针,所以 mem_fun_ref 可以工作) )。
The problem is that binder1st defines operator() as:
and mem_fun1_t defines operator() as:
The problem is that push_back is defined as:
So what we end up with is this:
And:
In other words, a reference to a reference to a pointer. A reference to a reference doesn't exist in C++. The only decent way I can think of fixing this is to use boost::bind instead:
Also note that you had a bug, and need to pass bind &ret instead of just ret (as mem_fun expects a pointer, mem_fun_ref would work however).
对容器中的整个项目集调用成员函数的最简单方法是使用
for_each
:如果您没有
tr1
,则可以使用:我不确定不过你想在这里实现什么。您同时具有编译时多态性(又名模板)和运行时多态性(又名
虚拟
成员函数)。设计似乎有点太复杂了。事实上,下面的定义就足够了:但是,正如您可能已经发现的那样,虚拟成员需要具有相同的签名才能在子类中被重写(否则您将重载该函数)。
请注意,示例
GetItems
不会调用所包含对象的成员函数,而是调用vector
容器对象上的成员,即push_back
。如果您只想将指针从普通数组复制到矢量,您可以使用矢量的专用构造函数,该构造函数需要两个迭代器:
The easiest way to call member functions on the entire set of items in your container is to use
for_each
:If you don't have
tr1
you can use:I am not sure what you are trying to achieve here though. You have both compile time polymorphism (aka templates) and runtime polymorphism (aka
virtual
member functions). The design seems a bit too complicated. In fact the following definition suffices:However, as you may have found out,
virtual
members need to have the same signature in order to be overriden in sub-classes (otherwise you are overloading the function).Note that the sample
GetItems
does not call a member function of the contained objects, it calls a member, namely,push_back
on thevector
container object.If all you want to do is to copy the pointers from a vanilla array to a
vector
you could usevector
's specialized ctor that takes two iterators: