c++ - 从引用创建一个指向基类的智能指针
问题描述
我有一个容器,它存储一个智能指针到基类的向量,我想通过一种方法填充它,而不需要我的用户也创建那个智能指针:
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
和 emplacement,除了我担心派生的内容不会被正确移动。
可能我在 Rust 土地上花了太多时间,这种移动非常普遍,所以如果我在这里离基地很远,请告诉我。理想情况下,该接口看起来像我的 #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>();
}
推荐阅读
- ios - 仅将角半径应用于顶部和底部单元时面临设计问题
- typo3 - TYPO3 在流体中裁剪图像
- c# - 为记录套接字通信创建一个高效的日志库
- javascript - 显示不同的图标,如果数字是 1 或 0 - ASP.NET C# MVC JQuery
- groovy - 如何在某个步骤中暂停所有线程组,直到其他线程组中的进程完成 - Jmeter
- sql - SQL Server 使用查找转换导入的数据
- algorithm - 我们可以构建的三角形数量
- node.js - 从一个数组 Firestore (Firebase) 中选择随机值
- powerbi - 修复内存密集型计算列
- c - 良好的风格实践:C 变量