如何在C ++(c ++ 11/c ++ 17)中执行元组算术?

编程入门 行业动态 更新时间:2024-10-18 18:16:25
本文介绍了如何在C ++(c ++ 11/c ++ 17)中执行元组算术?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在尝试编写模板功能/运算符,例如+,以便在两个相同类型的元组之间进行算术运算.例如,对于

I'm trying to write template functions/operators such as + for doing arithmetic operations between two tuples of the same type. For example, for

std::tuple<int,double> t = std::make_tuple(1,2);

我想做

auto t1 = t + t;

逻辑很简单:按元素进行算术运算.但是我不知道如何在c ++模板编程(c ++ 11/17)中实现这一功能.我下面的代码无法使用g++ -std=c++11 tuple_arith.cpp进行编译.特别是,我无法弄清楚使通用add函数(template<typename T> T add(T x, T y) { return x + y; })与元组操纵代码一起工作的正确方法.

The logic is simple: to do the arithmetic element-wise. But I can't figure out how to make this work in c++ template programming (c++11/17). My code below doesn't compile with g++ -std=c++11 tuple_arith.cpp. In particular, I can't figure out the right way of getting the generic add function (template<typename T> T add(T x, T y) { return x + y; }) to work with the tuple manipulating code.

有人可以帮忙解释如何解决此问题吗?

#include <tuple> namespace std { template<typename _Tp, size_t __i, size_t __size, typename _opT > struct __tuple_arith { static constexpr _Tp __op(const _Tp& __t, const _Tp& __u, const _opT& op) { return std::tuple_cat(std::make_tuple(op(std::get<__i>(__t), std::get<__i>(__u)) , __tuple_arith<_Tp, __i + 1, __size, _opT>::__op(__t, __u))); } }; template<typename _Tp, size_t __size, typename _opT> struct __tuple_arith<_Tp, __size, __size - 1, _opT> { static constexpr _Tp __op(const _Tp& __t, const _Tp& __u, const _opT& op) { return std::make_tuple(op(std::get<__size-1>(__t), std::get<__size -1>(__u))); } }; template<typename T> T add(T x, T y) { return x + y; } template<typename... _TElements> constexpr tuple<_TElements...> operator+(const tuple<_TElements...>& __t, const tuple<_TElements...>& __u) { using op = __tuple_arith<tuple<_TElements...>, 0, sizeof...(_TElements), decltype(add)>; return op::__op(__t, __u, add); } }; //namespace std #include <iostream> using namespace std; int main() { std::tuple<int,double> t = std::make_tuple(1,2); auto t1 = t + t; cout << std::get<0>(t1) << std::endl; return 0; }

具体错误是:

tuple_arith.cpp:14:10: error: template argument ‘(__size - 1)’ involves template parameter(s) struct __tuple_arith<_Tp, __size, __size - 1, _opT> { ^ tuple_arith.cpp: In function ‘constexpr std::tuple<_Elements ...> std::operator+(const std::tuple<_Elements ...>&, const std::tuple<_Elements ...>&)’: tuple_arith.cpp:24:90: error: decltype cannot resolve address of overloaded function __tuple_arith<tuple<_TElements...>, 0, sizeof...(_TElements), decltype(add)>; ^ tuple_arith.cpp:24:91: error: template argument 4 is invalid __tuple_arith<tuple<_TElements...>, 0, sizeof...(_TElements), decltype(add)>; ^ tuple_arith.cpp:25:12: error: ‘op’ has not been declared return op::__op(__t, __u, add); ^ tuple_arith.cpp: In instantiation of ‘constexpr std::tuple<_Elements ...> std::operator+(const std::tuple<_Elements ...>&, const std::tuple<_Elements ...>&) [with _TElements = {int, double}]’: tuple_arith.cpp:34:17: required from here tuple_arith.cpp:26:3: error: body of constexpr function ‘constexpr std::tuple<_Elements ...> std::operator+(const std::tuple<_Elements ...>&, const std::tuple<_Elements ...>&) [with _TElements = {int, double}]’ not a return-statement } ^

-更新-

感谢您到目前为止提供的有用答案.是否有可能使其适用于任何操作员包装器,例如std::{plus,minus,multiplies,divides}?这就是我试图通过模板参数typename _opT实现的目标.最后,我正在寻找可以将兼容运算符作为参数的函数/对象.

Thanks for the helpful answers so far. Is it possible to make it work for any Operator Wrappers, e.g. std::{plus,minus,multiplies,divides}? That's what I was trying to achieve with the template parameter typename _opT. In the end, I'm looking for a function/object that can take a compatible Operator as a parameter.

推荐答案

您的代码中的问题是,您无法基于另一个模板值对模板值进行部分专业化处理.您可以解决这个问题,但是...为什么?

The problem in your code is that you cannot partial specialize a template value based over another template value; you can go round this problem but... why?

用std::index_sequence

#include <tuple> #include <iostream> template <typename ... Ts, std::size_t ... Is> std::tuple<Ts...> sumT (std::tuple<Ts...> const & t1, std::tuple<Ts...> const & t2, std::index_sequence<Is...> const &) { return { (std::get<Is>(t1) + std::get<Is>(t2))... }; } template <typename ... Ts> std::tuple<Ts...> operator+ (std::tuple<Ts...> const & t1, std::tuple<Ts...> const & t2) { return sumT(t1, t2, std::make_index_sequence<sizeof...(Ts)>{}); } int main () { std::tuple<int,double> t = std::make_tuple(1,2); auto t1 = t + t; std::cout << std::get<0>(t1) << std::endl; std::cout << std::get<1>(t1) << std::endl; }

无论如何...我不认为将操作符添加到标准类型不是一个好主意.也许您只能定义一个sumT()函数.

Anyway... I don't think it's a good idea add operators to standard types; maybe you can only define a sumT() function.

P.s .: std::index_sequence和std::make_index_sequence是c ++ 14/17的功能;但不太复杂,可以在c ++ 11中对其进行仿真.

P.s.: std::index_sequence and std::make_index_sequence are c++14/17 features; but isn't too complex simulate they in c++11.

-编辑-

OP询问

非常感谢,是否可以使任何操作程序包装程序都可以使用此功能?请查看更新

Thanks a lot, is it possible to make this work for any operators wrappers? Please see the update

我想你的意思如下

#include <tuple> #include <iostream> #include <functional> template <typename Op, typename Tp, std::size_t ... Is> auto opH2 (Op const & op, Tp const & t1, Tp const & t2, std::index_sequence<Is...> const &) { return std::make_tuple( op(std::get<Is>(t1), std::get<Is>(t2))... ); } template <typename Op, typename Tp> auto opH1 (Op const & op, Tp const & t1, Tp const & t2) { return opH2(op, t1, t2, std::make_index_sequence<std::tuple_size<Tp>{}>{}); } template <typename ... Ts> auto operator+ (std::tuple<Ts...> const & t1, std::tuple<Ts...> const & t2) { return opH1(std::plus<>{}, t1, t2); } template <typename ... Ts> auto operator- (std::tuple<Ts...> const & t1, std::tuple<Ts...> const & t2) { return opH1(std::minus<>{}, t1, t2); } template <typename ... Ts> auto operator* (std::tuple<Ts...> const & t1, std::tuple<Ts...> const & t2) { return opH1(std::multiplies<>{}, t1, t2); } template <typename ... Ts> auto operator/ (std::tuple<Ts...> const & t1, std::tuple<Ts...> const & t2) { return opH1(std::divides<>{}, t1, t2); } int main () { std::tuple<int,double> t = std::make_tuple(1,2); auto t1 = t + t; auto t2 = t - t; auto t3 = t * t; auto t4 = t / t; std::cout << std::get<0>(t1) << ", " << std::get<1>(t1) << std::endl; std::cout << std::get<0>(t2) << ", " << std::get<1>(t2) << std::endl; std::cout << std::get<0>(t3) << ", " << std::get<1>(t3) << std::endl; std::cout << std::get<0>(t4) << ", " << std::get<1>(t4) << std::endl; }

更多推荐

如何在C ++(c ++ 11/c ++ 17)中执行元组算术?

本文发布于:2023-11-29 20:23:14,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1647528.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:算术   如何在

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!