Избыточные экземпляры в логических константных выражениях

У меня есть n-любой логический OR функция времени выполнения 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...);
}

а также аналог времени компиляции 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(), "");
};

оба из которых содержат утверждения (во время выполнения или во время компиляции, соответственно), чтобы гарантировать, что первый аргумент является истинным.

Теперь дает следующий вклад

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

утверждение во время выполнения никогда не завершается ошибкой, а во время компиляции — нет. Это означает, что any_run(false, false) однако никогда не вызывается any_comp <_false, _false> действительно создается, несмотря на то, что логическое константное выражение

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

можно оценить true если A() == true никогда не создавая any_comp <B...>,

Мой вопрос Является ли этот эксперимент и его заключение действительными, и что стандарт сказал бы об этом.

Это важно, потому что, если заключение верное, мне придется более тщательно (с большим количеством специализаций) повторно реализовать несколько функций времени компиляции, чтобы ускорить компиляцию, хотя я обычно предпочитаю делать вещи максимально простыми.

2

Решение

Короткое замыкание работает только на уровне времени выполнения для ||, Во время компиляции вам нужно что-то еще, например:

#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>();
}
3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]