【问题标题】:Implementation of std::disjunction in the Standard Library标准库中 std::disjunction 的实现
【发布时间】:2018-04-28 20:42:21
【问题描述】:

我在标准库 (source) 中看到了 std::disjunction 的实现:

template<class...> struct disjunction : std::false_type { };
template<class B1> struct disjunction<B1> : B1 { };
template<class B1, class... Bn>
struct disjunction<B1, Bn...>
    : std::conditional_t<bool(B1::value), B1, disjunction<Bn...>> { };

我很好奇需要将disjunction&lt;B1&gt; 专业化为B1。为什么它比我幼稚的实现更好?

template<class...>              struct or_t
    : std::false_type {};
template<class B1, class... Bn> struct or_t<B1, Bn...>
    : std::integral_constant<bool, bool(B1::value) || bool(or_t<Bn...>::value)> {};

【问题讨论】:

  • 请注意 std::disjunction 短路。
  • @Zereges 这可能是一个答案;)
  • 这肯定不是标准库实现...

标签: c++ c++17 standard-library


【解决方案1】:

你返回std::integral_constant

std::disjunction 返回给定类型之一(可能有其他成员)。

【讨论】:

  • 由于所有Bs 可能有不同的类型,std::disjunction&lt;B...&gt; 返回::value 成员转换为true 的第一个类型。这不是有点奇怪吗?制作一个有趣的选择器/(a)buses sfinae 可能很有用...
【解决方案2】:

此外,disjunction&lt;B1,...,BN&gt; 是必需的,如果它们都是假的,则导致最后一个给定类型 (BN)(请参阅 [meta.logical#10.2])。

一元特化 disjunction&lt;B1&gt; 在递归序列的尾部实现此行为。

例如,如果没有一元特化,如果B1::valuetruedisjunction&lt;B1&gt; 将给出B1,否则std::false_type


由于所有 B 可能具有不同的类型,std::disjunction 返回其 ::value 成员转换为 true 的第一个类型。这不是有点奇怪吗?制作一个有趣的选择器可能很有用

确实,我从未使用过这一系列特征(还),但它似乎是一个非常灵活的抽象:

template<class T>
struct some_condition: std::bool_constant</*whatever*/>
{
  using payload = T;
};

// take the first T satisfying some_condition, or last T if none does
disjunction<some_condition<T>...>::payload

// take the first T satisfying some_condition, or none
disjunction<some_condition<T>...,none_type>::payload

我唯一讨厌 disjunction 的就是它的名字......

【讨论】:

    猜你喜欢
    • 2014-10-06
    • 1970-01-01
    • 1970-01-01
    • 2019-07-11
    • 1970-01-01
    • 2019-12-17
    • 2018-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多