如何将 std::vector<boost::shared_ptr<T>> 复制到 std::list<T>

How to copy std::vector<boost::shared_ptr<T>> to std::list<T>

本文关键字:lt gt std 复制 list ptr shared vector boost      更新时间:2023-10-16
std::list<KinBody::Link::Geometry> geometries = link->GetGeometries();

link->GetGeometries()的类型为std::vector<boost::shared_ptr<Geometry>>使用上面的代码,我得到了以下错误:

error: conversion from ‘const std::vector<boost::shared_ptr<OpenRAVE::KinBody::Link::Geometry> >’ to     non-scalar type ‘std::list<OpenRAVE::KinBody::Link::Geometry>’ requested
std::list<KinBody::Link::Geometry> geometries = link->GetGeometries();
std::list<KinBody::Link::Geometry> geometries;
for (auto const & p : link->GetGeometries())
    geometries.push_back(*p);

对于for (auto const & p : ...)部分,您需要启用c++ 11支持(它使用自动类型推导和基于范围的For循环)。

在c++ 11之前是等价的

std::list<KinBody::Link::Geometry> geometries;
typedef std::vector<boost::shared_ptr<KinBody::Link::Geometry>> geometries_vector_t;
geometries_vector_t const & g = link->GetGeometries();
for (geometries_vector_t::const_iterator i = g.begin(); i != g.end(); ++i)
    geometries.push_back(**i); // dereferencing twice: once for iterator, once for pointer

注:这一切看起来很不自然。作为共享指针返回的对象意味着KinBody::Link::Geometry实际上是一个基类或接口,或者这种类型的对象很大,接口被设计成避免大量复制,或者其他什么。我建议不要像接口建议的那样复制对象并将它们存储为共享指针,除非您确实知道您需要这些副本。

既然你提到了boost,让我给你看看boost Range糖。

link->getgeometries() | adaptors::indirected

将产生一个包含Geometry&元素的范围。用copy_range:

填充列表
geometries = boost::copy_range<std::list<link::geometry>>(
        link->getgeometries() | adaptors::indirected
    );

查看完整的工作演示:

Live On Coliru

#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/make_shared.hpp>
#include <iostream>
namespace KinBody {
    struct Link {
        struct Geometry {};
        std::vector<boost::shared_ptr<Geometry> > GetGeometries() const {
            return {};
        }
    };
}
int main() {
    using namespace boost;
    using namespace KinBody;
    auto link = make_shared<Link>();
    auto geometries = boost::copy_range<std::list<Link::Geometry>>(
            link->GetGeometries() | adaptors::indirected
        );
}

std::list<KinBody::Link::Geometry> geometries = link->GetGeometries();

尝试将vector赋值给list。编译器告诉您不能这样做。你所要做的就是迭代vector并将每个元素插入到list中。

注意,vector包含指向几何图形的共享指针,而list声明包含实例。如果要在列表中存储指针,必须声明为:

std::list<KinBody::Link::Geometry*>  // note the *