集合中的智能指针多态性

Igo*_*evo 5 c++ polymorphism pointers shared-ptr initializer-list

我试图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();
}
Run Code Online (Sandbox Code Playgroud)

代码打印:

AA

它应该打印:

AB

有没有一种简单的方法可以做到这一点,而无需在调用方法中创建指针?

相关文章(如何使用std :: shared_ptr实现多态?)没有为这个问题提供太多帮助.

eer*_*ika 5

std::initializer_list<T>按值保存传递的对象,因此不能存在多态。也std::make_shared<A>总是创建一个类型的对象A,而不是一些派生自的类型A。你需要另一种方法。

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

编辑:我的代码建议太复杂了。WhozCraig 的评论要好得多:

template<class... Args>
Test(Args&&... args) :
    vec { std::make_shared<std::remove_reference_t<Args>>(std::forward<Args>(args))... }
{
}
Run Code Online (Sandbox Code Playgroud)