3

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 的类型必须在编译时知道,它取决于它的值。

4

1 回答 1

5

您可以在链接到的页面上找到解释:

析取是短路:如果有一个模板类型参数Bibool(Bi::value) != false那么实例化disjunction<B1, ..., BN>::value不需要实例化Bj::valuefor j > i

短路行为涉及value每个参数类型的成员,而不是参数类型本身。您无法在不知道模板参数的情况下实例化模板。并且使用std::disjunction<…&gt;通常需要实例化。在你的例子中

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

编译器仍然必须实例化std::bool_constant<does_not_compile()>,以便它知道整体std::disjunction<…&gt;结果是什么(正如您自己所指出的那样)。可以保证的是它不会实例化std::bool_constant<does_not_compile()>::value……

于 2019-04-01T21:03:32.880 回答