【问题标题】:is constexpr algorithm really useful, when iterator (input parameters) are not constexpr generally?当迭代器(输入参数)通常不是 constexpr 时,constexpr 算法真的有用吗?
【发布时间】:2018-07-24 05:50:42
【问题描述】:

在c++ 20中提出,一些算法是constexpr。

例如:

template< class InputIt, class UnaryPredicate >
bool all_of( InputIt first, InputIt last, UnaryPredicate p );
(since C++11)
(until C++20)


template< class InputIt, class UnaryPredicate >
constexpr bool all_of( InputIt first, InputIt last, UnaryPredicate p );
(since C++20)

虽然我们知道迭代器通常不是 constexpr。我认为这仅在 constexpr 容器的情况下才有用。有人可以澄清我是否遗漏了什么以及我的理解是否正确?

【问题讨论】:

  • 迭代器类型是一个模板参数,可以是your_custom_iterator,它具有允许此函数为 constexpr 的 constexpr 属性!
  • 意见问题与堆栈溢出无关。
  • 这与意见无关。正如奥利弗提到的一个很好的理由。
  • @code707 这绝对是一种意见。 “真的有用”无法客观回答。即使它是客观的,这个问题对于堆栈溢出来说也太宽泛了,因为全面讨论什么可能使它有用(以及这是否真的有用)将是大量的。
  • @xaxxon..有用可能是合乎逻辑的理由。

标签: c++ c++20


【解决方案1】:

确实如此。让我们尝试另一种算法,据我所知,constexpr 在 C++20 中还不是 std::iota。但是定义一个constexpr 版本并不难(我只是从cppreference 复制了示例实现并在上面打了constexpr):

template<class ForwardIterator, class T>
constexpr void my_iota(ForwardIterator first, ForwardIterator last, T value)
{
    while(first != last) {
        *first++ = value;
        ++value;
    }
}

那么有用吗?是的。只要迭代器是作为评估常量表达式的一部分创建的,算法的评估就可以出现在常量表达式中。例如:

template<std::side_t N, typename T>
constexpr make_iota_array(T start = {}) {
  std::array<T, N> ret{};
  my_iota(ret.begin(), ret.end(), start);
  return ret;
}

上面创建了一个用 iota 算法初始化的数组。如果函数作为评估常量表达式的一部分被调用,则对象ret 被创建为评估的一部分,它的迭代器也是如此。这些是有效的:

constexpr auto a1 = make_iota_array<10, int>();
constexpr auto a2 = make_iota_array<10>(0u);

【讨论】:

  • 这是否意味着,如果用于 constexpr 算法,迭代器上的所有操作必须也是 constexpr
  • @Klaus 不,只有你使用的那些
猜你喜欢
  • 2017-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-28
相关资源
最近更新 更多