user1079475 user1079475 - 27 days ago 14
C++ Question

C++11 Create compile time boolean expresion with variadic template arguments

Let say i have following base struct

struct Functor
{
virtual bool execute()=0;
};


On which base i created structs A, B and C.
Now i want to evaluate boolean expression on variadic list of these objects which i would at runtime do like this:

bool evaluate(list<Functor> objs)
{
for(list<Functor>::iterator it = objs.begin(); it!=objs.end();++it)
{
if(!it->execute())
return false;
}
return true;
}


My question is can i by having function declared like this

template<typename ...F>
static bool doEvaluation(F... args)
{
return... args->execute();
}


And executing it like this

doEvaluation(new A(), new B(), new C());


In the end get something like this at compile time?

return new A()->execute() && new B()->execute() && new C()->execute();

Nim Nim
Answer

You can implement something like what you are after, as follows:

#include <functional>
// overload for single argument
template <typename T>
constexpr bool check(T&& f) {
    return f();
}

// extract the first parameter then recursively call self for others
template <typename U, typename... T>
constexpr bool check(U&& f, T&&... t) {
    // this will short-circuit...
    return f() && check(std::forward<T>(t)...);
}

template <typename T, bool V>
struct A {
  // this method can be called at compile time
  constexpr bool operator()() const {
      return V;
  }
};

int main()
{
  constexpr auto v1 = check(A<int, true>{}, A<int, false>{}, A<double, true>{});
  static_assert(v1 == false, "expected false!");
  constexpr auto v2 = check(A<int, true>{}, A<int, true>{}, A<double, true>{}, A<float, true>{});
  static_assert(v2, "expected true!");
}

I'm sure it's possible to simplify this further. The inheritance stuff is not necessary, and the computation of the flags is done at compile time.