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等语言的功能。是的,编程模型有点不同,它更多地处理不可变对象。我还想