c – 使用std :: get,std :: tuple_size,std :: tuple_element对元组的组件求和

我有一个具有类似元组的界面的自定义类.因为我希望我的代码尽可能通用,我认为将算法基于函数std :: get,std :: tuple_size,std :: tuple_element是一个好主意,所以你只需要专门化这些函数使用我的算法.让我们调用需要这些函数特化元组的概念.

现在我试图总结一个元组的组件.函数声明应该是这样的:

template <class Tuple>
int sum_components(const Tuple& t);

我想有很多模板编程涉及但我无法弄清楚如何做到这一点.

对于添加,我只使用全局运算符的重载.

我正在使用c 1z.

最佳答案
这在很容易.

template<class Tuple>
decltype(auto) sum_components(Tuple const& tuple) {
  auto sum_them = [](auto const&... e)->decltype(auto) {
    return (e+...);
  };
  return std::apply( sum_them, tuple );
};

或(… e)相反的折叠方向.

在以前的版本中,正确的方法是编写自己的应用程序,而不是编写定制的实现.当您的编译器更新时,您可以删除代码.

,我可能会这样做:

// namespace for utility code:
namespace utility {
  template<std::size_t...Is>
  auto index_over( std::index_sequence<Is...> ) {
    return [](auto&&f)->decltype(auto){
      return decltype(f)(f)( std::integral_constant<std::size_t,Is>{}... );
    };
  }
  template<std::size_t N>
  auto index_upto() {
    return index_over( std::make_index_sequence<N>{} );
  }
}
// namespace for semantic-equivalent replacements of `std` code:
namespace notstd {
  template<class F, class Tuple>
  decltype(auto) apply( F&& f, Tuple&& tuple ) {
    using dTuple = std::decay_t<Tuple>;
    auto index = ::utility::index_upto< std::tuple_size<dTuple>{} >();
    return index( [&](auto...Is)->decltype(auto){
      auto target=std::ref(f);
      return target( std::get<Is>( std::forward<Tuple>(tuple) )... );
    } ); 
  }
}

这与中的std :: apply非常接近.(我滥用std :: ref来获取INVOKE语义). (它与rvalue调用者无法完美配合,但这种情况非常糟糕).

,我建议在此时升级您的编译器.在,我建议你升级你的工作.

以上所有都做右或左折叠.在某些情况下,二叉树折叠可能更好.这比较棘手.

如果您使用表达式模板,由于生命周期问题,上述代码将无法正常工作.您可能必须为“afterwards,cast-to”添加另一个模板类型,以便在某些情况下评估临时表达式树.

转载注明原文:c – 使用std :: get,std :: tuple_size,std :: tuple_element对元组的组件求和 - 代码日志