集合中的智能指针多态性

Smart pointer polymorphism in collections

本文关键字:指针 多态性 智能 集合      更新时间:2023-10-16

我试图通过初始化列表初始化A的指针集合。但是,初始化器列表不能将引用用作模板类型。

我有以下代码。

#include <iostream>
#include <functional>
#include <algorithm>
#include <vector>
#include <initializer_list>
#include <memory>
struct A
{
    virtual void f() const noexcept { std::cout << "A"; }
};
struct B : public A
{
    virtual void f() const noexcept override { std::cout << "B"; }
};
class Test
{
    std::vector<std::shared_ptr<A>> vec;
public:
    Test(const std::initializer_list<A>& list)
    //Test(const std::initializer_list<A&>& list) <------ Solution?
    {
        for (auto& x : list)
            vec.push_back(std::make_shared<A>(x));
    }
    void print()
    {
        std::for_each(vec.begin(), vec.end(), [](auto x) { x->f(); });
    }
};
int main()
{
    Test test = { A(), B() };
    test.print();
}

代码打印:

aa

它应该打印:

ab

有没有一种简单的方法来执行此操作,而无需在调用方法中创建指针?

相关文章(我如何用std :: shared_ptr实现多态性?)没有在此问题上提供太多帮助。

std::initializer_list<T>按值保持传递的对象,因此不可能有多孔症。另外,std::make_shared<A>总是制造一个类型A的对象,而不是源自A的某种类型。您需要另一种方法。

由于您有任意数量的具有任意类型的参数,因此您可能需要一个variadic模板构造函数。

编辑:我的代码建议太复杂了。Whozcraig的评论更好:

template<class... Args>
Test(Args&&... args) :
    vec { std::make_shared<std::remove_reference_t<Args>>(std::forward<Args>(args))... }
{
}

您正在使用std::make_shared<A>()插入向量。您将一堆BA复制到一堆A中。

如果您要主管中的语法工作,那么最简单的方法就是一个模板:

struct Foo {
    template<typename... Args>
    Foo(Args... args) :
        vec{std::make_shared<Args>(std::move(args))...}
    {}
private:
    std::vector<std::shared_ptr<A>> vec;
};

您在以下行中制作新的shared_ptr s

        vec.push_back(std::make_shared<A>(x));

x是什么都没关系,您制作了一个具有其值的新A

您可能要创建shared_ptr<A>并将指针从x.get()传递到新的空shared_ptr<A>