В каком смысле короткое замыкание std :: disjunction во время компиляции - PullRequest
3 голосов
/ 01 апреля 2019

Из описания на cppreference.com у меня сложилось впечатление, что std :: disjunction предназначен для того, чтобы обеспечить мне короткое замыкание во время компиляции, чтобы я мог использовать его следующим образом:

#include <type_traits>
#include <iostream>

template<nullptr_t null = nullptr>
constexpr bool does_not_compile() {
    static_assert(null != nullptr);
    return false;
}

void hello_world () {
    if constexpr (std::disjunction_v<std::true_type, std::bool_constant<does_not_compile()>>) {
        std::cout << "Hello World!" << std::endl;
    }
}

Однако это не компилируется, std :: disjunction не закорачивает в том смысле, что вышеуказанный static_assert не срабатывает ( живой пример ).

Но тогда какой смысл это короткое замыкание? Это не может быть обычным поведением || во время выполнения, потому что тип std :: disjunction должен быть известен во время компиляции, и это зависит от его значения.

1 Ответ

5 голосов
/ 02 апреля 2019

Вы найдете объяснение прямо на странице, на которую вы ссылаетесь:

Разъединение имеет короткое замыкание: если есть аргумент типа шаблона Bi с bool(Bi::value) != false, то создание экземпляра disjunction<B1, ..., BN>::value не требует создания экземпляра Bj::value для j> i

Режим короткого замыкания касается элемента value каждого типа параметра, а не самого типа параметра. Вы не можете создать экземпляр шаблона, не зная его параметров. А использование std::disjunction<…> обычно требует создания экземпляра. В вашем примере

std::disjunction_v<std::true_type, std::bool_constant<does_not_compile()>>

компилятору все еще нужно создать экземпляр std::bool_constant<does_not_compile()>, чтобы он знал, каким будет весь std::disjunction<…> (как вы сами отметили). Что гарантировано, так это то, что он не будет создавать экземпляр std::bool_constant<does_not_compile()>::value & hellip;

...