如何将派生类的shared_ptrs向量转换为基类的share_ptrs向量

Mar*_*rin 9 c++ stl

class Interface
{
};

class Class : public Interface
{
};

class Foo
{
public:
    std::vector<std::shared_ptr<Interface>>& GetInterfaces()
    {
        return *(std::vector<std::shared_ptr<Interface>>*)(&m_data);
        //return m_data;
    }

private:
    std::vector<std::shared_ptr<Class>> m_data;
};
Run Code Online (Sandbox Code Playgroud)

这有效,但是很丑陋和可怕.有没有更好/更安全的方法呢?我不想制作m_data类型,std::vector<std::shared_ptr<Interface>>因为模块Foo属于完全与Classs 一起工作,Interface(和Foo::GetInterfaces())被实现为与应该只知道Interface功能的单独模块交互.

让我知道如果这里的任何事情都不清楚,这对我来说是有意义的,但我已经在一段时间内对这个问题嗤之以鼻.

111*_*111 9

铸造不正确,它们是不同的类型; 我很确定你正在调用未定义的行为.

您需要构造一个新的向量并按值返回它.

std::vector<std::shared_ptr<Interface>> b (m_data.begin(), m_data.end());
return b;
Run Code Online (Sandbox Code Playgroud)

这仍应相当便宜(1次分配).


pmr*_*pmr 5

除此之外,这在 的实现中是不可能的vector,问题还在于引用不会转换。您的代码更糟糕并且是未定义的行为。

您可以做的是提供一个公开范围的接口,或者begin/end代替容器本身。如果您将其与transform_iterator进行转换的 a 结合起来,您应该已经设置好了。

示例代码:

class Interface {
  virtual ~Interface();
};

class X : public Interface {};

class C {

private:
  typedef std::shared_ptr<Interface> iptr_type;
  typedef std::shared_ptr<Class> ptr_type;
  std::vector<ptr_type> v_;

  struct F {
    iptr_type 
    operator()(ptr_type p) { return iptr_type(p); }
  };

  typedef boost::transform_iterator<
    F, std::vector<ptr_type>::iterator> iiterator;

public:
  iiterator
  begin()
  { 
    return boost::make_transform_iterator(
      begin(v_), F()); 
  }

  iiterator
  end()
  { 
    return boost::make_transform_iterator(
      end(v_), F());
  }
};
Run Code Online (Sandbox Code Playgroud)