使用 std::function 在对象列表上调用任何对象成员函数
Call any object member function on a list of objects using std::function
我有一个对象列表,我需要在其中调用成员函数 - 到目前为止没什么大不了的:遍历列表,进行调用 - 完成。
现在我有很多地方几乎在同一个列表上做同样的事情,除了被调用的成员函数改变(参数总是相同的,双精度值)。
我尝试了一些 std::function,但最终无法正常工作。有什么建议么? (我在使用 C# 多年后又回到了 C++,所以忘记了很多)。
这是现在的样子:
void CMyService::DoSomeListThingy(double myValue)
{
for (std::list<CMyListItem*>::iterator v_Iter = myList.begin(); v_Iter != myList.end(); ++v_Iter)
{
(*v_Iter)->MethodToBeCalled(myValue);
}
}
void CMyService::DoSomeThingDifferent(double myValue)
{
for (std::list<CMyListItem*>::iterator v_Iter = myList.begin(); v_Iter != myList.end(); ++v_Iter)
{
(*v_Iter)->CallTheOtherMethod(myValue);
}
}
这就是我喜欢的方式:
void CMyService::DoSomeListThingy(double myValue)
{
ApplyToList(&CMyListItem::MethodToBeCalled, myValue);
}
void CMyService::DoSomeThingDifferent(double myValue)
{
ApplyToList(&CMyListItem::CallTheOtherMethod, myValue);
}
void CMyService::ApplyToList(std::function<void(double)> func, double myValue)
{
for (std::list<CMyListItem*>::iterator v_Iter = myList.begin(); v_Iter != myList.end(); ++v_Iter)
{
(*v_Iter)->func(myValue);
}
}
void CMyService::ApplyToList(void (CMyListItem::*func)(double), double myValue) {
for (auto p : myList) {
(p->*func)(myValue);
}
}
使用 C++11 之前的编译器:
void CMyService::ApplyToList(void (CMyListItem::*func)(double), double myValue) {
for (std::list<CMyListItem*>::iterator v_Iter = myList.begin();
v_Iter != myList.end(); ++v_Iter) {
((*v_Iter)->*func)(myValue);
}
}
你可以使用 lambdas
void CMyService::ApplyToList(std::function<void(CMyListItem*, double)> func, double myValue))
{
for (std::list<CMyListItem*>::iterator v_Iter = myList.begin(); v_Iter != myList.end(); ++v_Iter)
{
func(*v_Iter, myValue);
}
}
和
double val;
std::function<void(A*,double)> fun1 = [=](A *th,double) {
th->foo(val);
};
std::function<void(A*,double)> fun2 = [=](A *th,double) {
th->bar(val);
};
ApplyToList(fun1, val);
ApplyToList(fun2, val);
我有一个对象列表,我需要在其中调用成员函数 - 到目前为止没什么大不了的:遍历列表,进行调用 - 完成。
现在我有很多地方几乎在同一个列表上做同样的事情,除了被调用的成员函数改变(参数总是相同的,双精度值)。
我尝试了一些 std::function,但最终无法正常工作。有什么建议么? (我在使用 C# 多年后又回到了 C++,所以忘记了很多)。
这是现在的样子:
void CMyService::DoSomeListThingy(double myValue)
{
for (std::list<CMyListItem*>::iterator v_Iter = myList.begin(); v_Iter != myList.end(); ++v_Iter)
{
(*v_Iter)->MethodToBeCalled(myValue);
}
}
void CMyService::DoSomeThingDifferent(double myValue)
{
for (std::list<CMyListItem*>::iterator v_Iter = myList.begin(); v_Iter != myList.end(); ++v_Iter)
{
(*v_Iter)->CallTheOtherMethod(myValue);
}
}
这就是我喜欢的方式:
void CMyService::DoSomeListThingy(double myValue)
{
ApplyToList(&CMyListItem::MethodToBeCalled, myValue);
}
void CMyService::DoSomeThingDifferent(double myValue)
{
ApplyToList(&CMyListItem::CallTheOtherMethod, myValue);
}
void CMyService::ApplyToList(std::function<void(double)> func, double myValue)
{
for (std::list<CMyListItem*>::iterator v_Iter = myList.begin(); v_Iter != myList.end(); ++v_Iter)
{
(*v_Iter)->func(myValue);
}
}
void CMyService::ApplyToList(void (CMyListItem::*func)(double), double myValue) {
for (auto p : myList) {
(p->*func)(myValue);
}
}
使用 C++11 之前的编译器:
void CMyService::ApplyToList(void (CMyListItem::*func)(double), double myValue) {
for (std::list<CMyListItem*>::iterator v_Iter = myList.begin();
v_Iter != myList.end(); ++v_Iter) {
((*v_Iter)->*func)(myValue);
}
}
你可以使用 lambdas
void CMyService::ApplyToList(std::function<void(CMyListItem*, double)> func, double myValue))
{
for (std::list<CMyListItem*>::iterator v_Iter = myList.begin(); v_Iter != myList.end(); ++v_Iter)
{
func(*v_Iter, myValue);
}
}
和
double val;
std::function<void(A*,double)> fun1 = [=](A *th,double) {
th->foo(val);
};
std::function<void(A*,double)> fun2 = [=](A *th,double) {
th->bar(val);
};
ApplyToList(fun1, val);
ApplyToList(fun2, val);