質問

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.

役に立ちましたか?

解決

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>();
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top