template<class T, typename... Args>
class Wrapper
{
// simple way of representing pointer-to-member
template <class T, class V>
using mv = V T::*;
public:
// non-type arguments (which are pointers to member)
template<mv<T, Args>... Ptrs>
static void fun(T* t)
{
make_tuple(t->*Ptrs...);
}
};
// inefficient one
template <typename... Args>
void fun_dynmaic_(Args&... args)
{
make_tuple(args...);
}
// actual class
class Apple
{
int a; float b; string c;
public:
Apple(int a, float b, const string& c) : a(a), b(b), c(c) {}
void fun_dynamic()
{
fun_dynmaic_(a, b, c);
}
void fun_static1()
{
make_tuple(a, b, c);
}
void fun_static2()
{
Wrapper<Apple, int, float, string>::fun<&Apple::a, &Apple::b, &Apple::c>(this);
}
};
我要处理某个类的所有成员变量。
简单地假设它是make_tuple()
。
在这里,我带来了3种实现方法。
我不确定,但是经过编译优化和内联之后,fun_static1()
和fun_static2()
将被编译成几乎相同的高效机器代码。就像这样:指向Apple
的指针,并使用实体偏移量直接访问每个成员。
fun_dynamic()
效果很好,但带有变量的所有地址。因此它必须是低效的。
在大多数情况下,选择fun_static1()
似乎是最好的。简单,快捷。但是,在某些情况下,我可能会有一些巨大的需求。例如,有class Banana, class Orange ...
,并且该任务(应在Apple, Banana..
的所有成员上完成)可能非常复杂但可重用的例程(而不仅仅是make_tuple()
)。如果那样的话,我必须要有一个模板。
fun_static1()
。如果我关心运行时性能,则必须选择fun_static2()
而不是fun_dynamic()
。对吧?
最后,
constexpr
,因此可以作为模板的参数。fun_static1()
的功能模板。void*
来计算成员偏移量。我是对的吗?那么,每当我认真考虑运行时性能时,是否应该实际实现fun_static2()
?
(我永远不会这么做,只是出于好奇)
编辑-如果您不需要模板,只需简单地以为我想在fun_dynmaic_()
上重用 Apple
'的成员,Banana
等等。然后,如果有很多变量,则实施fun_static2()
而不是fun_dynamic()
会很麻烦,但是(似乎)是更快的解决方案。
Edit2 -三种功能的作用完全相同:复制 a,b,c的值并放入一个元组。 (这只是一个例子)