Command template without virtual functions (C ++)

For performance reasons, I use the Curiously Reoccuring Template Pattern to avoid virtual functions. I have many small commands that run millions of times. I am trying to set this in Command Pattern. I want to add a ton of commands to the queue, and then iterate over them, each executing one at a time. Each team uses CRTP to avoid virtual functions. The problem I am facing is that the Command pattern is usually implemented using a pointer vector. But when the Command templated pattern, it becomes difficult to pass generic command pointers. I'm not an expert in C ++, so maybe there is an obvious way to store the vector of the template objects of the command? I am trying to use something like:

boost:ptr_vector commands; AddCommand(Command* command) { commands.push_back(command); } 

The Command problem is not a type, so Command* command gives a compilation error. I need to use Command<CommandType> , but this will not work, because I need a queue to store different types of commands.

Any ideas for solutions? Or are these virtual functions just for me?

ADDED: Command objects are part of the monte carlo simulation algorithm. That way you can have the Command command as a random number from the normal distribution, where the normal distribution parameters are part of the class. Thus, the command template fits very well. I have a lot of calls in a specific order for functions that must support state.

+4
source share
3 answers

CRTP does its magic by allowing the runtime type of an object at compile time so that the compiler can inline function calls. If you have a vector of pointers to a generic type, the compiler cannot determine a specific concrete type and cannot execute its temporary resolution.

Of all that you have in your question, I believe that virtual functions are your best option. However, virtual functions are not so slow. Of course, they are slower than the built-in function, but in many cases they are fast enough! Especially if your process is limited by I / O, rather than processing time.

One of the answers to this question has a more detailed discussion of this problem. In summary, the overhead of invoking a virtual function is likely to be measured in nanoseconds. This is more complicated, but the fact is that you should not be afraid of virtual functions if your function does not do something really trivial, as one purpose. You said that your teams were small, so perhaps this is so. I would try to make a quick prototype with virtual functions and make sure that this gives acceptable performance.

+11
source

If you do not create your command queue at compile time, then what you want is not possible.

+1
source

I can’t say if your lineup changes often or rarely.

If it rarely changes, compared to how often it runs, it seems to me that this might be a task for generating code.

Just print the program to perform the necessary actions, compile and link the DLL on the fly and load it. It takes about a second. No classes, objects, or dispatch. And if you take a one-step action, you will almost not see cycles that do not make a significant contribution to your answer.

+1
source

Source: https://habr.com/ru/post/1286042/


All Articles