dimanche 26 juillet 2015

(Compile-time) unit testing which of several overloads is called

Consider the following piece of code:

    struct A {};
    struct B : A {};

    bool f(A,A) { /* ... */ }
    bool f(B,B) { /* ... */ }

Now suppose I have somewhere something like

    // ...
    b = f(x,y);
    // ...

I would like to ensure by a (probably compile-time, or alternatively run-time) unit test that a particular overload of f is called by this sequence of code. Let's say f(B,B) is some specialized, optimized version of f(A,A), so that it is functionally equivalent, yet faster. I cannot determine which function has been called by just looking at the result.

One possibility, of course, is letting f set some global flag.

Another possibility is something like

   template <class X, class Res> struct Distinguish {
       using Tag = X;
       Res m_res;
       explicit Distinguish (Res res) : m_res (res) { }
       operator Res () const { return m_res; }
   };

   Distinguish<char[1], bool> f (A, A) { /* ... */ }
   Distinguish<char[2], bool> f (B, B) { /* ... */ }

and then examine decltype(f (x,y))::Tag. Yet that is ugly, since I have to change the signatures of f.

Is there any better way?

Aucun commentaire:

Enregistrer un commentaire