c++ 替换调用对象方法的宏函数

c++ Replace macro fuction that calls a method of an object

本文关键字:函数 方法 对象 替换 调用 c++      更新时间:2023-10-16

我正在处理一个无法完全重写的代码。在代码中的某个地方,我有这个片段

#define ITERATE_AND_CALL(vectorOfObjs, function)
do
for(auto & v : vectorOfObjs)
{
v.function();
}
while(false)

稍后在代码中,它在几个地方像这样调用

class Foo {
public:
void foo(){}
int foo2(){ return 1;}
}
std::vector<Foo> vecOfFoos;
ITERATE_AND_CALL(vecOfFoos, foo)
ITERATE_AND_CALL(vecOfFoos, foo2)

没有宏可以做到这一点吗?

do/while(false)的事情是一种在if语句中使用宏时保护宏免受事故的方法。

你可以用一个漂亮的函数模板替换宏:

template <typename Container, typename FPtr>
void ITERATE_AND_CALL(Container& container, FPtr callable)
{
for (auto& v : container)
(v.*callable)();
}

(现场演示(

几乎是一个直接的替换,除了你不能只传递函数的名称......你必须使用地址运算符:

struct Foo
{
void func() {}
};
int main()
{
std::vector<Foo> v(3);
ITERATE_AND_CALL(v, &Foo::func);
}

所以&Foo::func而不仅仅是func.这是没有办法的。


但是,如果您可以进一步修改调用站点,则有更好的方法来执行此操作,这些方法不会限制您使用函数指针和无参数回调:

template <typename Container, typename Callable>
void IterateAndCall(Container& container, Callable func)
{
for (auto& v : container)
func(v);
}

现在,您的func可以是lambda或任何其他绑定您喜欢的东西,例如

std::vector<int> vecOfFoos{1,2,3};
IterateAndCall(vecOfFoos, [](const int v) { std::cout << v; });

这几乎只是std::for_each的较短,重新发明的版本。如果你到了这个地步,你可能应该只使用std::for_each......或者干脆写出循环。

c++ 替换调用对象
方法的宏函数 无论如何,没有宏就可以做到这一点吗?

看起来像是std::for_each的工作:

#include <algorithm>
#include <vector>
#include <iostream>
struct Foo {
void foo() {
std::cout << "a_funcn";
}
};
#define ITERATE_AND_CALL(vector, function)
do
for(auto & v : vector)
{
v.function();
}
while(false) 
int main()
{
std::vector<Foo> vecOfFoos(2);
ITERATE_AND_CALL(vecOfFoos, foo);
std::for_each(vecOfFoos.begin(), vecOfFoos.end(), [](auto& v) {
v.foo();
});
}

这将产生 2 个a_func输出用于ITERATE_AND_CALL和 2 个输出用于std::for_each

a_func
a_func
a_func
a_func