# Tagged Operators ## Dealing with pre-C++17 Many applications and libraries in HPC are written using an Object-Oriented design. This has numerous advantages in terms of code organization and potentially reuse. Unfortunately it comes with a significant drawback as far as using Kokkos is concerned, if C++17 is not an option. Consider an application for simulating the time evolution of a particle system. In an Object-Oriented design, it would likely contain something like a class `ParticleInteractions`, which holds references to data structures for particles and interaction potentials. It would also contain some member function `compute`, which would loop over the particles and calculate the interactions: ```c++ class ParticleInteractions { ParticlePositions pos; ParticleForces forces; ParticleNeighbors neighbors; PairForce force; public: void compute() { for(int i=0; ineighbors.count(i); j++) { this->forces(i) = this->force(this->pos(i),this->pos(this->neighbors(i,j))); } }); } }; ``` If `this` is not dereferenceable in the scope of the execution space, the execution will fail. In C++17 the situation can be rectified by using the `[*this]` capture clause. In that case, the whole class instance will be captured and copied to the accelerator as part of the dispatch. One way to deal with this situation pre-C++17 is to simply make a corresponding operator for the compute function, and dispatch the class itself as a functor: ```c++ class ParticleInteractions { ... void compute() { parallel_for("Compute", *this); } KOKKOS_FUNCTION void operator() (const int i) const { for(int j=0; j(0,N), *this); parallel_for("Compute2", RangePolicy(0,N), *this); } KOKKOS_FUNCTION void operator() (TagPhase1, const int i) const { ... } KOKKOS_FUNCTION void operator() (TagPhase2, const int i) const { ... } }; ``` ## Templating Operators Another useful application of the tagged interface is the opportunity to template operators. A particular use case has been the conversion of runtime loop parameters into compile time ones: