【问题标题】:how to determine if split_apply() is noexcept?如何确定 split_apply() 是否为 noexcept?
【发布时间】:2021-11-01 19:15:07
【问题描述】:

我有这个转发函数,它可能会抛出也可能不会抛出,这取决于参数是什么:

template <std::size_t M>
constexpr void split_apply(auto f, auto&& ...a) // noexcept(?)
{
  // transforms provided tuple t into a tuple of N-element tuples
  constexpr auto split([]<std::size_t N>(auto&& t) noexcept requires (bool(N))
    {
      constexpr auto n(std::tuple_size_v<std::remove_cvref_t<decltype(t)>>);
      static_assert(n && !(n % N));
      return [&]<auto ...I>(std::index_sequence<I...>) noexcept
        {
          return std::make_tuple(
            [&]<auto ...J>(std::index_sequence<J...>) noexcept
            {
              constexpr auto K(N * I);
              return std::forward_as_tuple(std::get<K + J>(t)...);
            }(std::make_index_sequence<N + I - I>())...
          );
        }(std::make_index_sequence<n / N>());
    }
  );

  std::apply([&](auto&& ...t) noexcept(noexcept(
    (std::apply(f, std::forward<decltype(t)>(t)), ...)))
    {
      (std::apply(f, std::forward<decltype(t)>(t)), ...);
    },
    split.template operator()<M>(std::forward_as_tuple(a...))
  );
}

由于std::apply() 没有noexcept 说明符(IMO 缺陷),因此这里可能也不应该有任何说明符,但我们假设它有一个。我如何计算 split_apply() 是否会抛出一些提供的参数?

【问题讨论】:

  • 我不知道是否有帮助,但noexcept 是签名的一部分,例如给定void f() noexcept;,然后static_assert(std::is_same_v&lt;decltype(f), void()noexcept&gt;); 通过,但static_assert(std::is_same_v&lt;decltype(f), void()&gt;); 没有。也许你可以if constexpr 以某种方式?
  • noexcept operator 执行编译时检查,如果声明表达式不引发任何异常,则返回 true。它可以在函数模板的 noexcept 说明符中使用,以声明函数将为某些类型抛出异常,但不会为其他类型抛出异常。
  • 我想我需要澄清我想要什么,std::apply() 没有noexcept 说明符,但std::invoke() 有。我希望我的函数有一个(正确的)noexcept 说明符,就像std::invoke() 一样。有时std::invoke()noexcept,有时不是。
  • noexcept(std::is_nothrow_invocable_v&lt;decltype(f), decltype(a)...&gt;) 呢?
  • @Evg 是的,但参数包必须以某种方式拆分,结果与结果为 AND。

标签: c++ c++20 noexcept


【解决方案1】:

我解决这个问题的方法(伪代码):

constexpr bool is_nothrow_function(/*repeat arguments*/) noexcept
{
  return noexcept(
    // repeat function body
  );
}

同样的方法可以用来修复std::applyan implementation is available on my GitHub page

【讨论】:

    猜你喜欢
    • 2021-08-05
    • 1970-01-01
    • 2016-04-05
    • 2013-09-10
    • 1970-01-01
    • 2020-04-02
    • 2019-06-24
    • 2017-06-24
    • 1970-01-01
    相关资源
    最近更新 更多