0

There is a lightweight class that plays the central role in a code. Actually, there are two variants (say, V0 and V1); both have method do_it(). This method takes about 10 floating point operations (FPOs) in V0 and about 20 FPOs in V1. This is a small number but do_it() is being called all the time and overall these calls take 30% - 70% of execution time.

In my current implementation V0 and V1 are template parameters for all other classes that depend on them so the correct variant of do_it() is decided at compilation.

The problem is basically any class in the code uses V or uses a class that uses V, so in practice all classes are templates. Over time it becomes a bit annoying and hard to maintain.

What other mechanism of C++ can I use instead of the templates? Can anyone estimate an overhead for this case? Of course I will learn the actual numbers when I rewrite the code, but this is quite an investment

EDIT Let me also provide a (very simplified) example:

Let's say V0 and V1 are points in 2D space. V0 is on a plane and V1 on a sphere. do_it() is a method that calculates the distance between points and in the case of V0 is much faster than for V1

Then I have classes e.g. Points<V> which inherits from a std::vector<V>, RandomWalk<V> that keeps a reference to Points<V>, lots of analysis code like plot_distribution<V>(Points<V>) etc.

Maybe at some point in the future a user will be allowed to provide their own geometries e.g. a torus. But as for now there are only two geometries allowed and they never appear in the program both at the same time.

tnorgd
  • 1,530
  • 2
  • 13
  • 24

2 Answers2

3

Good old macros are still perfectly usable.

#define NS NS_ ## VARIANT;

namespace NS 
{
  using Variant = VARIANT;

  class Foo
  {
    Variant* v;
    // etc
  };
  // everything goes here

}

Now compile the entire project twice, once with -DVARIANT=V0, once with -DVARIANT=V1. No overhead!

n. 1.8e9-where's-my-share m.
  • 102,958
  • 14
  • 123
  • 225
0

If you know that your template parameter will be limited to certain classes (say V0 and V1) then you can move all your template code to .cpp files as normal and get it to link as follows...

Header (.h)

template<class T>
class Foo
{
public:
   void Do();
};

Implementation (.cpp)

template<class T>
void Foo::Do()
{
   ///do stuff...
}

//this creates two entries in the object code for link time resolution of Foo<V0> and Foo<V1> but Foo<anything else> will fail to link
template class Foo<V0>;
template class Foo<V1>;
keith
  • 4,973
  • 1
  • 20
  • 42