patterncppMinor
Plugin system for calling methods
Viewed 0 times
systemmethodspluginforcalling
Problem
I have a small "plugin system" (I'm not sure this is the right name). It allow you to store objects (plugins), and then call some methods from each of them. With this approach we have absolutely no overhead on iterating/object pass/callback call.
Then, when I need to call some function from each of plugins, or do something with each of them, I iterate through plugins at compile time (I check this with generated asm code, and it just calls or even
And if I need to do something with a specific plugin, I just directly use
Is it ok to store rvalue references on objects, or I have to store objects directly in my tuple?
Like this:
When I iterate, I pass a plugin as a usual reference:
```
struct Call{
float k=0;
template // 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:
// 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::forward_as_tuple( // Pay attention here. We store &&, not objects
plugin1,
plugin2,
plugin3
));Then, when I need to call some function from each of plugins, or do something with each of them, I iterate through plugins at compile time (I check this with generated asm code, and it just calls or even
inline do_it, without anything else) and call the callback function (I'm not showing iterate code here; it's trivial):struct Call{
float k=0;
template // 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;
}
};And if I need to do something with a specific plugin, I just directly use
plugin1, plugin2, and plugin3. No need to call std::get<>. Plus the IDE highlights available plugins when you type them.Is it ok to store rvalue references on objects, or I have to store objects directly in my tuple?
Like this:
SET(plugins, std::tuple(
Plugin1(param1, param2),
Plugin2(param1, param2),
Plugin3(param1, param2)
));When I iterate, I pass a plugin as a usual reference:
```
struct Call{
float k=0;
template // 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:
Solution
First, you are not storing
Second, you can use a tuple of references as you would use a reference itself. That is, everything is fine unless you return a tuple of references to local objects, in which case references are dangling.
Third, between forwarding (
which keeps a reference to lvalues, and copies rvalues only. I find this most convenient.
In general, storing references or objects depends on what you want to do. Think of what you would choose if it was only one object, then keep the same choice for the tuple.
Check here for more.
&&, but rather &. Why? because plugin1 etc. are lvalue references, and because of the reference collapsing rules.Second, you can use a tuple of references as you would use a reference itself. That is, everything is fine unless you return a tuple of references to local objects, in which case references are dangling.
Third, between forwarding (
forward_as_tuple) and copying (make_tuple) there's another option:template
constexpr std::tuple auto_tuple(A&&... a)
{
return std::tuple(std::forward(a)...);
}which keeps a reference to lvalues, and copies rvalues only. I find this most convenient.
In general, storing references or objects depends on what you want to do. Think of what you would choose if it was only one object, then keep the same choice for the tuple.
Check here for more.
Code Snippets
template<class... A>
constexpr std::tuple<A...> auto_tuple(A&&... a)
{
return std::tuple<A...>(std::forward<A>(a)...);
}Context
StackExchange Code Review Q#51062, answer score: 3
Revisions (0)
No revisions yet.