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,580
  • 2
  • 14
  • 24
  • Why is this annoying? Have you put everything in header files? – n. m. could be an AI Jul 08 '16 at 09:48
  • Yes, 90% if the code in in *.hh. I don't like it. – tnorgd Jul 08 '16 at 09:59
  • 2
    You can move method definitions to cpp files, and explicitly instantiate everything. You only need two instantiations for each class template, `someclass` and `someclass`. – n. m. could be an AI Jul 08 '16 at 10:03
  • @tnorgd You know you get [benefits](http://stackoverflow.com/questions/12671383/benefits-of-header-only-libraries) from header-only? – erip Jul 08 '16 at 10:37
  • @n.m would you mind providing more details, how should I implement the solution you propose? Have a look on my edited post: do I just need an explicit instantiation of every class that now is a template? E.g. can I move the whole implementation of ``RandomWalk`` to ``RandomWalk.cc`` and just declare ``RandomWalk`` and ``RandomWalk`` there? – tnorgd Jul 08 '16 at 10:38
  • Yes, that's exactly what you need. – n. m. could be an AI Jul 08 '16 at 11:22
  • So finally I decided to use the #define route – tnorgd Jul 19 '16 at 21:48

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. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
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
  • 5,122
  • 3
  • 21
  • 50