为c++中的对象列表调用object方法
Call object method for a list of objects in C++
如何为提供给函数的每个对象设计调用对象方法?
。
ResetAll(obj1, obj2, obj3, ...)
将调用obj1.Reset()
, obj2.Reset()
等…
对象不在List或其他STL容器中
可能是可变模板:
template <typename ...Objs> struct Resetter;
template <typename Obj, typename ...Rest> struct Resetter<Obj, Rest>
{
static inline void reset(Obj && obj, Rest &&... rest)
{
std::forward<Obj>(obj).Reset();
Resetter<Rest...>::reset(std::forward<Rest>(rest)...);
}
};
template <> struct Resetter<> { static inline void reset() { }; };
// Type-deducing helper
template <typename ...Objs> inline void ResetAll(Objs &&... objs)
{
Resetter<Objs...>::Reset(std::forward<Objs>(objs)...);
}
用法:
ResetAll(ob1, obj2, some_obj, another_obj);
概念证明,因为编写可疑的c++代码很有趣:
#include <vector>
#include <iostream>
using namespace std;
#define Invoke(A, T,M,...)
do{
struct _{
_& operator,(T* value){
value->M A ;
return *this;
}
} _; _, __VA_ARGS__;
}while(0)
#define m_a_all(...) Invoke( (), Obj,m_a,__VA_ARGS__)
#define m_b_all(...) Invoke( (), Obj,m_b,__VA_ARGS__)
#define m_c_all(A, ...) Invoke(A, Obj,m_c,__VA_ARGS__)
class Obj{
public:
virtual void m_a(){
cout << "Obj::m_a " << this << endl;
}
virtual void m_b(){
cout << "Obj::m_b " << this << endl;
}
virtual void m_c(int a, double b){
cout << "Obj::m_c(" << a <<"," << b<< ") " << this << endl;
}
};
class Derived : public Obj{
public:
virtual void m_a(){
cout << "Derived::m_a " << this << endl;
}
virtual void m_b(){
cout << "Derived::m_b " << this << endl;
}
virtual void m_c(int a, double b){
cout << "Derived::m_c(" << a <<"," << b<< ") " << this << endl;
}
};
int main(){
Obj *o1 = new Obj(), *o2 = new Obj(), *o3 = new Derived();
m_a_all(o1, o2, o3);
cout<<endl;
m_a_all(o1);
cout<<endl;
m_b_all(o1, o2, o3);
cout<<endl;
m_c_all( (3,42.0), o1, o2, o3);
return 0;
}
示例输出:
Obj::m_a 0x9e0a008
Obj::m_a 0x9e0a018
Derived::m_a 0x9e0a028
Obj::m_a 0x9e0a008
Obj::m_b 0x9e0a008
Obj::m_b 0x9e0a018
Derived::m_b 0x9e0a028
Obj::m_c(3,42) 0x9e0a008
Obj::m_c(3,42) 0x9e0a018
Derived::m_c(3,42) 0x9e0a028
链式operator,
过载允许__VA_ARGS__
被使用。一个限制是,它只能在所有参数共享一个基类型的情况下使用,而要调用的方法是为这个基类型定义的。
这应该有最小的开销,不依赖于任何库。
如果你能接受Boost对预处理器的严重滥用。预处理:
#include <boost/preprocessor.hpp>
#define CALL_RESET(z, n, data) BOOST_PP_CAT(p, n).Reset();
#define GENERATE_VARIADIC_FUNCTION(z, n, data)
template <BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(n), typename T)>
void ResetAll(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, BOOST_PP_INC(n), T, & p))
{
BOOST_PP_CAT(BOOST_PP_REPEAT_, z)(BOOST_PP_INC(n), CALL_RESET, )
}
/* ^ this generates the function
template <typename T0, typename T1, typename T2, ...>
void ResetAll(T0& p0, T1& p1, T2& p2, ...)
{
p0.Reset(); p1.Reset(); p2.Reset(); ...
}
*/
BOOST_PP_REPEAT(BOOST_PP_LIMIT_REPEAT, GENERATE_VARIADIC_FUNCTION, )
// ^ and this creates all of the above up to 256.
例如,#include <cstdio>
struct Obj1 { void Reset() { printf("1n"); } };
struct Obj2 { void Reset() { printf("2n"); } };
struct Obj3 { void Reset() { printf("3n"); } };
int main()
{
Obj1 o1;
Obj2 o2;
Obj3 o3;
ResetAll(o1, o2, o3, o2, o1, o3);
return 0;
}
将在屏幕上打印'1 2 3 2 1 3'(证明:http://ideone.com/FRNvJ)。
(顺便说一句,如果其中一个输入是右值,这将产生不可逾越的错误消息墙。)
相关文章:
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 函数调用中参数的顺序重要吗
- OpenGL - 在抛出"__gnu_cxx::recursive_init_error"实例后终止调用?
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在c++类上调用void函数
- 为什么 std::unique 不调用 std::sort?
- 调用专用模板时出错"no matching function for call to [...]"
- 选择要调用的构造函数
- C++为什么尽管我调用了void函数,它却不起作用
- 当覆盖存在时调用基本虚拟"binded to object"函数
- 使用 object 中的方法调用带有 std::bind 和 std::function.target 的 C 样式函数
- 在非构造"object"上调用非虚拟成员函数是否定义良好?
- 如何获取指向调用 (Q)Object 的方法的指针
- 在单独的线程中调用boost::python::object作为函数
- delete(Object) 等价于调用 Object.~Object() 吗?
- 在 c++ 中为 object 调用的方法
- 为c++中的对象列表调用object方法