我有一个目标标准向量:
std::vector<std::pair<float,float> > allVertices;
Run Code Online (Sandbox Code Playgroud)
为什么我要使用对,因为每2个浮点数呈现位置对(x,y).现在,我有一个源std :: vector,它具有所有这些位置但是作为float数组(称为m_vertices).
我需要将所有数据从m_vertices复制到allVertices的末尾,并在复制期间执行数据转换.
std :: transform让我想起了Lambda,但我无法弄清楚如何从float向量复制到float对的向量.
天真的:
std::transform(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) ;
}
);
Run Code Online (Sandbox Code Playgroud)
给我编译时错误:
错误C2064:术语不评估为带有1个参数的函数
还有一些比较难看的东西.
顺便说一句,如果有人可以指出如何在std :: pair结构中转换数据对而在我的情况下更有帮助.
更新:
由于一些使用典型迭代器的答案提议,我想强调我真的希望看到功能解决方案.如果有可能的话.
编译器消息在这里很清楚:你的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);
}
Run Code Online (Sandbox Code Playgroud)
确保尺寸m_vertices均匀; 否则这个代码会爆炸,当然.
Lamdas和函数式编程很不错,但有时简单地执行它更容易.
以下是如何编写一个使用lamdba进行缩减的函数:
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; // Input length not even!
auto& y = *it;
*d_first++ = reducer_op(x,y);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以将此函数与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) ;
}
);
Run Code Online (Sandbox Code Playgroud)
正如Steve Jessop在评论中正确指出的那样,编写自己的对迭代器更灵活,但也更有效.它可能看起来像这样(草图代码,这里没有编译器,可能包含小错误):
template<typename It> struct PairIterator {
private:
mutable It it; // mutable so we can move around in operator*
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); }
Run Code Online (Sandbox Code Playgroud)
现在你可以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) ;
}
);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
630 次 |
| 最近记录: |