Question

I have an n-any boolean OR run-time function any_run

#include <assert.h>

bool any_run() { return false; }

template <typename... B>
bool any_run(bool a, B... b)
{
    assert(a);
    return a || any_run(b...);
}

as well as a compile-time analogue any_comp

#include <type_traits>

template <bool E>
using expr = std::integral_constant <bool, E>;

using _true  = expr <true>;
using _false = expr <false>;

template <typename... A>
struct any_comp : public _false { };

template <typename A, typename... B>
struct any_comp <A, B...> : public expr <A() || any_comp <B...>()>
{
    static_assert(A(), "");
};

both of which contain assertions (run-time or compile-time, respectively) to ensure that the the first argument is true.

Now giving the following input

int main()
{
    any_run   (true,  false,  false);
    any_comp <_true, _false, _false>();
}

the run-time assertion never fails, but the compile-time one does. This means that any_run(false, false) is never called, however any_comp <_false, _false> does get instantiated, despite the fact that boolean constant expression

A() || any_comp <B...>()

could be evaluated to true if A() == true without ever instantiating any_comp <B...>.

My question is whether this experiment and its conclusion are valid, and what the standard would say about it.

It is important because if the conclusion is valid, I'd have to re-implement several compile-time functions more carefully (with more specializations) to make compilation faster, although I generally prefer to keep things as simple as possible.

Was it helpful?

Solution

Short-circuit only works on the run-time level for ||. At compile-time, you need something else like:

#include <type_traits>

template <typename T, typename U>
struct integral_or : U { };

template <typename U>
struct integral_or <std::true_type, U> : std::true_type { };

template <typename... A>
struct any_comp : std::false_type { };

template <typename A, typename... B>
struct any_comp <A, B...> : integral_or <A, any_comp <B...>>
{
    static_assert(A(), "");
};

int main()
{
    any_comp <std::true_type, std::false_type, std::false_type>();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top