我有一些小的“插件系统”(不确定这是正确的名称)。它允许您存储对象(插件),然后从每个对象中调用一些方法。使用这种方法,我们绝对没有迭代/对象传递/回调调用的开销。
// Need this SET, because in C++11 auto can only be static const.
// And we may need to change them later.
#ifndef SET
#define SET(NAME, VALUE) decltype(VALUE) NAME = VALUE
#endif
Plugin1 plugin1(param1, param2);
Plugin2 plugin2(param1, param2);
Plugin3 plugin3(param1, param2);
SET(plugins, std::tie( // Pay attention here. We store &, not objects
plugin1,
plugin2,
plugin3
));
然后,当我需要从每个插件调用一些函数,或者每个插件执行某些操作时,我会在编译时迭代插件(我使用生成的asm代码检查它,它只是调用甚至是inline do_it
,没有任何其他)和调用回调函数(我不在这里显示迭代代码,这是微不足道的):
struct Call{
float k=0;
template<typename T, int Index> // lambda function not efficient than this. Tested -O2 clang, gcc 4.8
inline void do_it(T &&t){
std::cout << "value = " <<t << " ; " << "id = " << Index << std::endl;
}
};
如果我需要使用特定的插件,我只需直接使用plugin1,plugin2,plugin3。无需致电std::get<>
。当您键入时,Plus IDE会突出显示可用的插件。
嗯,问题是。是否可以将rvalue引用存储在对象上,或者我必须将对象直接存储在我的元组中?像这样:
SET(plugins, std::tuple(
Plugin1(param1, param2),
Plugin2(param1, param2),
Plugin3(param1, param2)
));
当我迭代时,我像往常一样传递插件:
struct Call{
float k=0;
template<typename T, int Index> // lambda function not efficient than this. Tested -O2 clang, gcc 4.8
inline void do_it(T &t){
std::cout << "value = " <<t << " ; " << "id = " << Index << std::endl;
}
};
使用这种方法,我们对元组中的每个元素都有额外的移动构造函数调用。以前的版本是免费的。
我问这个,因为,之前我读过Data locality,现在我担心数据如何放在内存中。也许我甚至不必考虑这个......
更新
1)如果没有“SET”,我们会有这样的事情:
// in global scope
auto plugins = std::tie(
plugin1,
plugin2,
plugin3
);
没关系。直到全球范围。但是因为只有我们想把“插件”作为类成员,编译器才会要求它作为constexpr静态,它将成为:
struct MyClass{
static const Plugin1 plugin1(param1, param2);
static const Plugin2 plugin2(param1, param2);
static const Plugin3 plugin3(param1, param2);
static const auto plugins = std::tie(
plugin1,
plugin2,
plugin3
);
};
此处Is it possible to have an "auto" member variable?
2)关于生命时间...对于&amp;&amp;的第一种情况。我们分别保存对象,而我们的“插件”只包含对象的右值引用: