Tim*_*ney 3 c++ macros c-preprocessor
我想创建一个宏来定义一个在对象列表上调用该函数的函数.它不一定必须是预处理器宏,但它应该工作.
我想写这样的东西:
CALL_ON_ALL(doSomething(int arg1, bool arg2))
Run Code Online (Sandbox Code Playgroud)
我想要它产生这个:
void doSomething(int arg1, bool arg2) {
for (int i = 0; i < delegates.size(); i++)
delegates[i]->doSomething(arg1, arg2);
}
Run Code Online (Sandbox Code Playgroud)
我有一些有用的东西:
#define CALL_ON_ALL(defSig, callSig) \
void defSig { \
for (int i = 0; i < delegates.size(); i++) \
delegates[i]->callSig; \
}
Run Code Online (Sandbox Code Playgroud)
问题是我必须分别编写定义签名和调用签名,如下所示:
CALL_ON_ALL(doSomething(int arg1, bool arg2), doSomething(arg1, arg2))
Run Code Online (Sandbox Code Playgroud)
有一个更好的方法吗?
它不一定必须是预处理器宏.任何有效的方法都可以.
尝试使用单独的参数(对于两个参数)进行签名:
#define CALL_ON_ALL2(name, argType1, argName1, argType2, argName2) \
void name( argType1 argName1 , argType2 argName2 ) { \
for (int i = 0; i < delegates.size(); i++) \
delegates[0]->name( argName1 , argName2 ); \
}
Run Code Online (Sandbox Code Playgroud)
您可以将其复制为其他参数编号.
这是高阶函数的一个很好的例子,它是将另一个函数作为参数的函数.在这种情况下,要在每个元素上调用函数.
下面定义了一个调用f每个元素的高阶函数.它需要C++ 11用于可变参数模板(args...).如果您没有可用的C++ 11,则可以删除typename ...Args函数签名中的固定参数类型并使用它.
template<typename Delegates, typename Function, typename... Args>
void callOnAll(Delegates delegates, Function f, Args... args) {
for (int i = 0; i < delegates.size(); i++)
f(delegates[i], args...);
}
Run Code Online (Sandbox Code Playgroud)
现在您可以使用以下语法调用它:
callOnAll(delegates, std::mem_fun<void,Delegate>(&Delegate::doSomething), 42);
Run Code Online (Sandbox Code Playgroud)
该std::mem_fun事件为您要为每个委托调用的成员函数创建一个临时函数对象.您还可以应用其他函数,将指针作为其第一个参数.例如,这个小的lambda函数(也仅限于C++ 11):
callOnAll(delegates, [](Delegate *d){
d->doSomething(42);
});
Run Code Online (Sandbox Code Playgroud)
这几乎是一样的,只是另一种语法.
在这里查看示例:
std::mem_fun)这个代码略有不同的版本使用基于范围而不是基于索引的for循环,它看起来更清晰(也需要C++ 11):
template<typename Delegates, typename Function, typename... Args>
void callOnAll(Delegates delegates, Function f, Args... args) {
for(auto d : delegates)
f(d, args...);
}
Run Code Online (Sandbox Code Playgroud)
对于你的信息,有std::for_each几个你想要的东西,但是稍微更功能一些,因为它本身不需要函数参数,但是你提供了一个lambda函数/函子,它只接受一个指针实例.使用lambda函数将以下代码与上面的代码进行比较:
std::for_each(delegates.begin(), delegates.end(), [](Delegate *d){
d->doSomething(42);
});
Run Code Online (Sandbox Code Playgroud)
唯一的区别是我们必须传递.begin()和.end()迭代器而不是只有一个容器实例,比如delegates.但是,标准库中定义了许多其他算法值得关注!
| 归档时间: |
|
| 查看次数: |
11903 次 |
| 最近记录: |