Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何连锁C++`“转换”和“内部产品”调用?_C++ - Fatal编程技术网

C++ 如何连锁C++`“转换”和“内部产品”调用?

C++ 如何连锁C++`“转换”和“内部产品”调用?,c++,C++,我想做一些类似的事情: vector<int> v; v.push_back(0); v.push_back(1); v .transform([](auto i) { return i + 2; }) .transform([](auto i) { return i * 3; }) .inner_product(0); 向量v; v、 推回(0); v、 推回(1); v .transform([](自动i){返回i+2;}) .transform([]

我想做一些类似的事情:

vector<int> v;
v.push_back(0);
v.push_back(1);

v
    .transform([](auto i) { return i + 2; })
    .transform([](auto i) { return i * 3; })
    .inner_product(0);
向量v; v、 推回(0); v、 推回(1); v .transform([](自动i){返回i+2;}) .transform([](自动i){return i*3;}) .内积(0); 换句话说,只需隐式使用
begin()
end()
作为
first
last
迭代器,并链接结果


是否有任何东西(如某些库)允许这样做?

只需编写自己的类来扩充
std::vector

#include <algorithm>
#include <iostream>
#include <numeric>
#include <vector>
#include <utility>

template < typename T >
class augmented_vector
{
  std::vector < T > m_vec;
public:
  augmented_vector() : m_vec() {}
  explicit augmented_vector(std::vector<T> const& in) : m_vec(in) {}

  void push_back ( T&& value )
  {
    m_vec.push_back(std::forward<T>(value));
  }

  template < typename F >
  augmented_vector < T > transform(F const& f)
  {
    std::vector < T > new_vec(m_vec.size());
    std::transform( m_vec.begin(), m_vec.end(), new_vec.begin(), f);
    return augmented_vector < T > ( new_vec );
  }

  T inner_product(T value)
  {
    return std::inner_product( m_vec.begin(), m_vec.end(), m_vec.begin(), value);
  }
};

int main()
{
  augmented_vector<int> v;
  v.push_back(0);
  v.push_back(1);

  auto val = v
    .transform([](auto i) { return i + 2; })
    .transform([](auto i) { return i * 3; })
    .inner_product(0);

  std::cout << val << '\n';
}

只需编写自己的类来扩充
std::vector

#include <algorithm>
#include <iostream>
#include <numeric>
#include <vector>
#include <utility>

template < typename T >
class augmented_vector
{
  std::vector < T > m_vec;
public:
  augmented_vector() : m_vec() {}
  explicit augmented_vector(std::vector<T> const& in) : m_vec(in) {}

  void push_back ( T&& value )
  {
    m_vec.push_back(std::forward<T>(value));
  }

  template < typename F >
  augmented_vector < T > transform(F const& f)
  {
    std::vector < T > new_vec(m_vec.size());
    std::transform( m_vec.begin(), m_vec.end(), new_vec.begin(), f);
    return augmented_vector < T > ( new_vec );
  }

  T inner_product(T value)
  {
    return std::inner_product( m_vec.begin(), m_vec.end(), m_vec.begin(), value);
  }
};

int main()
{
  augmented_vector<int> v;
  v.push_back(0);
  v.push_back(1);

  auto val = v
    .transform([](auto i) { return i + 2; })
    .transform([](auto i) { return i * 3; })
    .inner_product(0);

  std::cout << val << '\n';
}

包装函数,在包装函数中提供样板文件:

template<typename Container, typename Transform>
void transform_container(Container & container, Transform transform) {
  std::transform(std::begin(container), std::end(container),
                 std::begin(container), /* requires output iterator */
                 transform);
}

template<typename T, typename Container>
auto inner_product_self(Container&& container, T initial) {
  return std::inner_product(std::begin(container), std::end(container),
                            std::begin(container),
                            initial);
}
模板
无效变换_容器(容器和容器,变换变换){
std::transform(std::begin(容器),std::end(容器),
std::begin(容器),/*需要输出迭代器*/
转化);
}
模板
自动内部产品(容器和容器,T首字母){
返回标准::内部产品(标准::开始(容器),标准::结束(容器),
标准::开始(容器),
首字母);
}
然后,您的代码变成:

int main() {
  std::vector<int> v(2);
  std::itoa(std::begin(v), std::end(v), 0);

  transform_container(v, [](auto i) { return i + 2; });
  transform_container(v, [](auto i) { return i * 3; });

  auto result = inner_product_self(container, 0);

  std::cout << "result: " << result;
}
intmain(){
std::向量v(2);
标准::itoa(标准::开始(v),标准::结束(v),0);
转换容器(v,[](自动i){returni+2;});
转换容器(v,[](自动i){returni*3;});
自动结果=内部产品自身(容器,0);

std::cout包装函数,在包装函数中提供样板文件:

template<typename Container, typename Transform>
void transform_container(Container & container, Transform transform) {
  std::transform(std::begin(container), std::end(container),
                 std::begin(container), /* requires output iterator */
                 transform);
}

template<typename T, typename Container>
auto inner_product_self(Container&& container, T initial) {
  return std::inner_product(std::begin(container), std::end(container),
                            std::begin(container),
                            initial);
}
模板
无效变换_容器(容器和容器,变换变换){
std::transform(std::begin(容器),std::end(容器),
std::begin(容器),/*需要输出迭代器*/
转化);
}
模板
自动内部产品(容器和容器,T首字母){
返回标准::内部产品(标准::开始(容器),标准::结束(容器),
标准::开始(容器),
首字母);
}
然后,您的代码变成:

int main() {
  std::vector<int> v(2);
  std::itoa(std::begin(v), std::end(v), 0);

  transform_container(v, [](auto i) { return i + 2; });
  transform_container(v, [](auto i) { return i * 3; });

  auto result = inner_product_self(container, 0);

  std::cout << "result: " << result;
}
intmain(){
std::向量v(2);
标准::itoa(标准::开始(v),标准::结束(v),0);
转换容器(v,[](自动i){returni+2;});
转换容器(v,[](自动i){returni*3;});
自动结果=内部产品自身(容器,0);


std::cout如果它在任何地方,它也会在,内积有两个范围:@MooingDuck,
boost::algorithm::join
是我真正想做的。听起来像是一个傻瓜,没有
std::vector::transform
,你必须使用(并重用)迭代器,或者范围(boost或Pstade.Oven)对于连接。如果它在任何地方,它也会在,内积有两个范围:@MooingDuck,
boost::algorithm::join
是我真正想要做的。听起来像是一个复制品,没有
std::vector::transform
,你必须使用(并重用)迭代器或范围(boost或Pstade.Oven)用于串联。该
变换
成员函数生成整个向量的两个副本!@DanielJour你确定吗?我认为它只生成一个副本(
新向量
),但它也可以实现为变异
增强向量
的状态。然而,这是人们通常不期望的,这就是我以这种方式实现它的原因。是的,
新向量
以及返回的
增强向量
的成员
m_向量
转换
成员函数由两部分组成整个向量的副本!@DanielJour你确定吗?我想它只复制了一份(
new\u-vec
),但它也可以实现为变异
augmented_vector
的状态。然而,这是人们通常不期望的,这就是我以这种方式实现它的原因。是的,
new_vec
以及返回的
augmented_vector
的成员
m_vec
。这仍然不是链接调用。链接cal如果容器的类型不同,或者容器本身需要是
const
@NoelYap,那么ls很重要。最后两条语句都不是真的。如果容器是
const
,或者如果您想为结果使用不同的容器,那么当然不能(就像我的代码那样)修改容器本身。您可以轻松地编写一个包装器函数,该函数使用并返回一个不同的容器(可能是不同类型的)。我想要的是像Groovy、Scala和Java 8这样的语言。是的,编程模型有点不同,它更多地处理不可变的对象。我也希望能够做到这一点,而不必手动编写代码。AFAIK调用std::transform会填充输出迭代器。因此,您正在遍历容器3 times!加上自然的趋势是语法链接。这将允许无缝地插入算法库中的现有函数。例如,std::find_if和std::remove。这是胡说八道的性能方面的,也应该语法链接以显示意图。Python默认情况下有此功能(iterables、生成器表达式)我不知道C++,也许是Boo::范围,正如上面提到的。它绝对需要STD的一部分,并且是用户友好的。这仍然没有链接调用。链接的调用是很重要的,如果容器的类型不一样,或者容器本身需要是代码> const 。@ NoelyAP既不是最后两个状态。ts是正确的。如果容器是
const
,或者如果您想要为结果使用不同的容器,那么当然您不能(就像我的代码那样)修改容器本身。您可以轻松地编写一个包装函数,使用它,然后返回一个不同的容器(可能是不同的类型)。我想要的是Groovy、Scala和Java 8等语言的功能。是的,编程模型有点不同,它更多地处理不可变对象。我还想