编译器信息很明确:你的lambda必须接受一个输入参数,但是你的lambda接受了两个输入参数x和y。你不能使用std::transform完成你的任务,因为std::transform只能处理单个值并将其转换,而不能处理值对。以下是三种可能实现任务的方法:
普通命令式编程
为什么不像这样简单地使用普通的非函数式方法呢:
for(auto it = m_vertices.begin(); it != m_vertices.end();++it){
float x = *it;
++it;
float y = *it;
all_vertices.emplace_back(x*100f,y*100f);
}
请确保m_vertices
的大小是偶数;否则,这段代码当然会出问题。
虽然lambda和函数式编程很好,但有时候以命令式的方式实现更容易。
编写自己的对转换函数
以下是使用lambda编写执行缩减的函数的示例:
template< class InputIt, class OutputIt, class BinaryReducerOp >
OutputIt transformPairs( InputIt first1, InputIt last1, OutputIt d_first,
BinaryReducerOp reducer_op );
for(auto it = first1; it != last1;++it){
auto& x = *it;
++it;
if(it == last1) throw;
auto& y = *it;
*d_first++ = reducer_op(x,y);
}
}
现在你可以将这个函数用于Lambda中。例如:
transformPairs(m_vertices.begin(),m_vertices.end(),allVertices.end(),
[](float x,float y)->std::pair<float,float>
{
return std::pair<float,float>(x * 100.0f,y * 100.0f) ;
}
);
编写一对迭代器
正如 Steve Jessop 在他的评论中所正确指出的那样,编写自己的一对迭代器更加灵活,但也需要更多的工作。它可能看起来像这样(示意代码,此处没有编译器,可能包含一些小错误):
template<typename It> struct PairIterator {
private:
mutable It it;
public:
typedef decltype(it*) Element;
PairIterator(const It& it) : it(it) {}
bool operator!=(const PairIterator<It>& other) const { return other != it; }
std::pair<Element, Element> operator*() const {
const Element& e1 = it*;
++it;
const Element& e2 = it*;
--it;
return std::make_pair(e1,e2);
}
PairIterator<It>& operator++(){
++it;
++it;
return *this;
}
}
template<typename It>
make_pair_it(const It& it){ return PairIterator<It>(it); }
现在你可以像这样使用
std::transform
:
std::transform(make_pair_it(m_vertices.begin()),make_pair_it(m_vertices.end()),allVertices.end(),
[](std::pair<float,float> p)->std::pair<float,float>
{
return std::pair<float,float>(p.first * 100.0f,p.second * 100.0f) ;
}
);
transform
函数有一个接受两个迭代器的版本,这种情况下您的lambda表达式将起作用。然而,您需要确保这两个输入迭代器分别返回向量的交替元素,请参考https://dev59.com/2m025IYBdhLWcg3w_a-r。 - Steve Jessop