有没有理由使用 std::conjunction/std::d isjunction 而不是 "&&" / "||" 上的折叠表达式?

Is there a reason to use std::conjunction/std::disjunction instead of a fold expression over "&&"/"||"?

本文关键字:std 表达式 折叠 isjunction 有理由 conjunction      更新时间:2023-10-16

是否有任何特定情况您无法使用std::conjunction/std::disjunction正确处理,并且不使用更"基本"(即语言功能而不是库功能)折叠表达式上的&&/||

示例:

// func is enabled if all Ts... have the same type
template<typename T, typename... Ts>
std::enable_if_t<std::conjunction_v<std::is_same<T, Ts>...> >
func(T, Ts...) {
 // TODO something to show
}

vs

// func is enabled if all Ts... have the same type
template<typename T, typename... Ts>
std::enable_if_t<(std::is_same<T, Ts> &&...)>
func(T, Ts...) {
 // TODO something to show
}

使用折叠表达式的版本更简短,通常更可读性(尽管意见可能有所不同)。因此,我不明白为什么它与折叠表达式一起添加到库中。

std::conjunction短路 ::value实例化,而折叠表达式则没有。这意味着给出:

template <typename T> 
struct valid_except_void : std::false_type { };
template <> 
struct valid_except_void<void> { };

以下将编译:

template <typename... Ts>
constexpr auto test = std::conjunction_v<valid_except_void<Ts>...>;
constexpr auto inst = test<int, void>;

但是以下内容不会:

template <typename... Ts>
constexpr auto test = (valid_except_void<Ts>::value && ...);
constexpr auto inst = test<int, void>;

godbolt.org上的实时示例


来自cppreference:

连词是短路的:如果有一个模板类型参数Bi bool(Bi::value) == false,则实例化conjunction<B1, ..., BN>::value不需要Bj::value的CC_10实例化。