转换为const向量

时间:2016-07-08 10:15:00

标签: c++ c++11

我手边有一些Foo的向量,我想将其转换为Bar s和const的向量。我能想到的最好方法是:

Bar foo2bar(const Foo& foo);

std::vector<Foo> foos = {...};

const std::vector<Bar> bars = [&foos] {
    std::vector<Bar> bars;
    bars.reserve(foos.size());
    std::transform(foos.cbegin(), foos.cend(),
                   std::back_inserter(bars),
                   foo2bar);
    return bars;
}();

我认为大多数编译器都应该省略lambda的返回值,所以这应该接近理想状态。唯一的缺点可能是需要创建一个lambda,但我不认为这是一个太大的问题。

这种方法是否存在任何隐蔽性问题,是否有更好的方法(例如,更快,更清洁)? C ++ 11可用。

3 个答案:

答案 0 :(得分:4)

您最简单的解决方案是完全放弃const要求。您仍然可以将引用 - const公开给其他范围。

如果做不到,这应该没问题。 lambda的身体可能会被内联,&#34;创造&#34; lambda是一个编译时进程,返回值将被移动或完全省略。实际上,你的方法非常优雅。

答案 1 :(得分:2)

如果你真的不能遵守lambda的想法,那么你可以达到提升transform_iterator

#include <vector>
#include <boost/iterator/transform_iterator.hpp>

struct Foo {};
struct Bar {};

Bar foo2bar(const Foo& f) {
    return Bar {};
}

int main()
{
    std::vector<Foo> foos = {  };

    using boost::make_transform_iterator;
    const std::vector<Bar> bars (make_transform_iterator(foos.begin(), &foo2bar),
                                 make_transform_iterator(foos.end(), &foo2bar));
}

然而,lambda在优化后没有性能损失,可以说不那么神秘,所以我鼓励这样做。

答案 2 :(得分:1)

或者,您可以将import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Point; import java.util.HashMap; import java.util.Map; import javax.swing.JFrame; import org.openstreetmap.gui.jmapviewer.Coordinate; import org.openstreetmap.gui.jmapviewer.JMapViewer; import org.openstreetmap.gui.jmapviewer.MapMarkerCircle; import org.openstreetmap.gui.jmapviewer.Style; /** * @see https://stackoverflow.com/a/38265252/230513 * @see https://stackoverflow.com/a/33857113/230513 */ public class RateCircleTest { private void display() { JFrame f = new JFrame("London"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JMapViewer map = new JMapViewer() { @Override public Dimension getPreferredSize() { return new Dimension(320, 240); } }; Coordinate london = new Coordinate(51.5072, -0.1275); map.setDisplayPosition(london, 16); Map<String, Integer> rates = new HashMap<>(); rates.put("London", 42); for (Map.Entry<String, Integer> entry : rates.entrySet()) { map.addMapMarker(new RateCircle(entry, london)); } f.add(map); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } private static class RateCircle extends MapMarkerCircle { private static final int R = 12; private Map.Entry<String, Integer> entry; public RateCircle(Map.Entry<String, Integer> entry, Coordinate coord) { super(null, "", coord, R, STYLE.FIXED, getDefaultStyle()); this.entry = entry; Style style = getStyle(); style.setBackColor(Color.cyan); style.setColor(Color.red); } @Override public void paintText(Graphics g, Point position) { super.paintText(g, position); g.drawString(entry.getKey(), position.x + R + 2, position.y + R); g.drawString(entry.getValue() + " kb/s", position.x + R + 2, position.y + R + g.getFontMetrics().getHeight()); } } public static void main(String[] args) { EventQueue.invokeLater(new RateCircleTest()::display); } } 功能移动到foo2bar()类作为转换运算符

Foo