是否有理由使用std :: conjunction/std :: disjunction而不是在“&///||"上的折叠表达式? [英] Is there a reason to use std::conjunction/std::disjunction instead of a fold expression over "&&"/"||"?

查看:53
本文介绍了是否有理由使用std :: conjunction/std :: disjunction而不是在“&///||"上的折叠表达式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在某些特殊情况下,您不能正确地使用 std :: conjunction / std :: disjunction 而不使用更多的基本"(即语言功能而不是库功能)在&& / || 上折叠表达式?

Is there any specific cases you cannot correctly do with std::conjunction/std::disjunction and not using the more "fundamental" (i.e. language feature instead of library feature) fold expression over &&/||?

示例:

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

使用fold表达式的版本更简短,通常更易读(尽管对此可能有不同的看法).因此,我不明白为什么将它与折叠表达式一起添加到库中.

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 短路了 :: value 实例化,而fold表达式没有.这意味着,鉴于:

std::conjunction short-circuits ::value instantiation, while the fold expression doesn't. This means that, given:

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 :

连接是短路的:如果存在带有 bool(Bi :: value)== false 的模板类型参数 Bi ,则实例化 conjunction<B1,...,BN> :: value 不需要实例化 j>的 Bj :: value .我.

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.

这篇关于是否有理由使用std :: conjunction/std :: disjunction而不是在“&amp;///||"上的折叠表达式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆