简体   繁体   English

是否有理由在 "&&"/"||" 上使用 std::conjunction/std::disjunction 而不是折叠表达式?

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

Is there any specific cases you cannot correctly do with std::conjunction / std::disjunction and not using the more "fundamental" (ie language feature instead of library feature) fold expression over && / ||是否有任何特定情况您无法正确使用std::conjunction / std::disjunction并且不使用更多“基本”(即语言功能而不是库功能)折叠表达式而不是&& / || ? ?

Example:例子:

// 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
}

The version using a fold expression is more brief and generally more readable (although opinions might differ on that).使用折叠表达式的版本更简洁,通常更易读(尽管对此意见可能有所不同)。 So I don't see why it was added to the library together with fold expressions.所以我不明白为什么它与折叠表达式一起添加到库中。

std::conjunction short-circuits ::value instantiation, while the fold expression doesn't. std::conjunction短路::value实例化,而折叠表达式则不然。 This means that, given:这意味着,给定:

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

template <> 
struct valid_except_void<void> { };

The following will compile:以下将编译:

template <typename... Ts>
constexpr auto test = std::conjunction_v<valid_except_void<Ts>...>;

constexpr auto inst = test<int, void>;

But the following won't:但以下不会:

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

constexpr auto inst = test<int, void>;

live example on godbolt.org Godbolt.org 上的现场示例


From cppreference :cppreference

Conjunction is short-circuiting: if there is a template type argument Bi with bool(Bi::value) == false , then instantiating conjunction<B1, ..., BN>::value does not require the instantiation of Bj::value for j > i .连接是短路的:如果有一个带有bool(Bi::value) == false的模板类型参数Bi ,那么实例化conjunction<B1, ..., BN>::value不需要实例化Bj::value j > i Bj::value

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM