1

I am going through Alexandrescu's book and it demonstrates the useful concept of typifying integral values to allow for compile-time dispatch:

template <int Val>
struct Elastic
{
    enum {V = Val};
};

template <class Object, bool isElastic>
class ImpactMomentum
{
    double calc_momentum(double v_in, Elastic<true> /*  */)
    {
        // compute elastic ...
    }

    double calc_momentum(double v_in, Elastic<false> /*  */)
    {
        // compute rigid ...
    }
 public:
    double calc_momentum(double v_in)
    {
        calc_velocity(v_in, Elastic<isElastic>());
    }
};

Is there a modern C++ implementation which supersedes this idiom? Something which scales well when there are multiple flags to toggle in the function's argument list.

2
  • 5
    I don't think there's anything that completely negates the usefulness of this, however if constexpr can be used if the code differences between makes that more suitable
    – SirGuy
    Commented May 25, 2020 at 17:58
  • 3
    Perhaps integral constant is what you're looking for.
    – cigien
    Commented May 25, 2020 at 18:00

1 Answer 1

3

Yes, there is. The idea is to use type instead of boolean (or numerical) expressions. Your case is rather trivial, but it is helpful when dealing with more complex properties, and is more open for later expansion.

I'll add another imaginary elasticity type "Alien", only for the sake of demonstratring expansion.

Consider this:

// empty types
struct Elastic { enum {V = Val}; };
struct Rigid   {};
struct Alien   {};

template <class Object, class Elasticity>
class ImpactMomentum
{
    // for libraries wanting to give users even more expansion options, 
    // without modifying the library, these specializations could be 
    // regular free functions also taking *this as a parameter, for 
    // example.

    double calc_momentum(double v_in, Elastic)  // or const & if property has data
    {
        // ...
    }

    double calc_momentum(double v_in, Rigid)
    {
        // ...
    }

    double calc_momentum(double v_in, Alien)
    {
        // ...
    }

 public:
    double calc_momentum(double v_in)
    {
        return calc_velocity(v_in, Elasticity{});
    }
};
3
  • The pattern you have described will allow for more variation for each parameter, but I was already able to do it. I could have replaced the bool with typifying an int. This will scales poorly if you have several arguments which you want to specialise about because there will be a lot of common boilerplate code. I may have misunderstood your suggestion?
    – Mansoor
    Commented May 26, 2020 at 8:16
  • Maybe... This pattern is used by many. Note that not it not onlty allows for properties with data but for deriving from properties for further specializtion. One thing that may add boilerplate code is the way code is structured and orgaznized, Elasticity would be better suited as a roperty of the object itself. Maybe having it as a property of a PhysicalObject class would make more sense. After all, calc_momentum is a function, not an object type. I did not include this analysis in the answer because that is out of the scope of the question. Commented May 27, 2020 at 0:47
  • As for boilerplate code, welcome to C++. Higher level concepts and powerful constructs that make the rest of the code easier to keep bug-free, easier to reason about and easier and faster to read and write must be declared somewhere at some point. Commented May 27, 2020 at 0:50

Not the answer you're looking for? Browse other questions tagged or ask your own question.