gpt4 book ai didi

c++ - 从引用创建一个指向基类的智能指针

转载 作者:行者123 更新时间:2023-12-02 10:02:41 25 4
gpt4 key购买 nike

我有一个存储智能指针到基类的 vector 的容器,我想通过一种方法填充它,而不需要我的用户也创建该智能指针:

class Base {
// ...
};
class Derived: public Base {
// ...
};

class Collection {
private:
vector<unique_ptr<Base>> pointers;

public:
void add(Base&& value) // #1
{
pointers.push_back(????);
}

void add<typename T>(T&& value) // #2
{
pointers.push_back(????);
}
};

int main() {
Collection collection;
collection.add(Derived("Data")); // #3
}

如果有的话,正确的方法是什么?很明显,我可以使用 make_unique和就位,除了我担心派生的内容不会被正确移动。

可能我在 Rust 土地上花了太多时间,这种移动非常普遍,所以如果我在这里离基地很远,请告诉我。理想情况下,该接口(interface)看起来像我的 #3 点,可以使用派生类型的文字调用该函数,而无需任何与分配或任何其他样板相关的额外样板。如果解决方案最终成为 Collection::add,我会找到通用的。

最佳答案

您可能应该坚持使用模板,是的。然后你得到

class Collection {
std::vector<std::unique_ptr<Base>> pointers;

public:
template<typename T>
void add(T &&value) {
pointers.emplace_back(std::make_unique<std::remove_reference_t<T>>(std::forward<T>(value)));
}
};

int main() {
Collection c;
Derived d;
c.add(d); // works with lvalues (copying)
c.add(std::move(d)); // or rvalues (moving)
Base b;
c.add(b);
c.add(std::move(b));
}

然而,提供一个“emplace”可能更有用,它用任意参数构造一个对象(所有标准容器都提供)
class Collection {
std::vector<std::unique_ptr<Base>> pointers;

public:
template<typename T, typename... Ts>
void emplace(Ts&&... args) {
pointers.emplace_back(std::make_unique<T>(std::forward<Ts>(args)...));
}
template<typename T> // still useful for conciseness (don't have to specify T)
void add(T &&value) {
this->emplace<std::remove_reference_t<T>>(std::forward<T>(value));
}
};

所以你可以进一步做
int main() {
Collection c;
Derived d;
c.add(d); // works with lvalues
c.add(std::move(d)); // or rvalues
c.emplace<Derived>(); // or can give arguments directly (assuming a default constructor, in this case)
Base b;
c.add(b);
c.add(std::move(b));
c.emplace<Base>();
}

A complete example on Godbolt.

关于c++ - 从引用创建一个指向基类的智能指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61807754/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com