c++ - 移动 shared_ptr进入 shared_ptr>
问题描述
我试图避免一组普通旧数据结构的相当复杂的继承链,但我需要将它们全部存储在向量中+与调用者共享所有权。
Struct A {};
Struct B {};
using TInstruction = std::variant<A, B>;
struct holder {
std::vector<std::shared_ptr<TInstruction>> items;
};
static holder h;
// Every individual TInstruction gets its own add function, for validation purposes
void add(std::shared_ptr<A> a) {
// Somehow add this to h, while still sharing ownership with the caller
// h.emplace_back(???)
}
int main() {
holder h;
auto a = std::make_unique<A>();
auto b = std::make_unique<B>();
add(a);
// add(b) // not implemented
}
通过对原始想法的以下更改,我取得了中等(但令人讨厌的差)成功:
- 在变体中使用共享指针,即
using TInstruction = std::variant<std::shared_ptr<A>, std::shared_ptr<B>>
- 接受一个 std::weak_ptr in
add()
并.lock()
用来将它变成一个 std::shared_ptr
我不介意#2(在我看来,这可能是正确的做法),但是将 shared_ptr 保持在它“外部”的变体内部会导致一些非常冗长的代码和模式匹配。
有可能做到这一点吗?我本质上想改变共享指针的类型,但仍然表达共享所有权的想法。
解决方案
只要您跟踪它自己持有的类型variant
,您就可以利用shared_ptr<void>
能够持有任何东西的优势,而不是使用,如下所示:shared_ptr
// Generic typelist
template <typename...>
struct Types;
// Find the 0-based index of type T in Types<...>
template <typename, typename>
struct Index;
// T is the first type in Types<...>
template <typename T, typename... Us>
struct Index<T, Types<T, Us...>> : std::integral_constant<int, 0> {};
// T is not the first type in Types<...>
template <typename T, typename U, typename... Us>
struct Index<T, Types<U, Us...>>
: std::integral_constant<int, 1 + Index<T, Types<Us...>>()> {};
template <typename... Ts>
struct SharedPtrVariant {
template <typename T>
explicit SharedPtrVariant(std::shared_ptr<T> p)
: sp(std::move(p)), index(Index<T, Types<Ts...>>()) {}
template <typename T>
std::shared_ptr<T> get() const {
return std::static_pointer_cast<T>(
Index<T, Types<Ts...>>() == index ? sp : nullptr);
}
private:
std::shared_ptr<void> sp;
int index;
};
推荐阅读
- regex - 如何使用 perl 获得期望值
- python - 联合查找算法不返回预期结果
- wordpress - 当其他 Chromium 浏览器正常工作时,Chrome 会显示 RESULT_CODE_INVALID_CMDLINE_URL
- amazon-web-services - AWS 相当于 Azure 构建块?
- php - 用户类中的 PHP 密码重散列(MySQL)
- .net - 如何在 WPF Gridview 的同一列中定义多个控件?
- vb.net - 接受空值的VB.Net函数?
- python - 在 python 中读取一个大文本文件会杀死我的程序
- tensorflow - TF2 Keras - Keras 中的特征工程通过 Tensorflow Serving 保存模型
- python - 如何通过仅使用 Python 和 Selenium 直接上传文件来避免打开文件对话框?