我试图编写一个向量 Package 器(indexed_vec
),它存储ValueType类型的对象,但其他数据结构(其他类型的向量)通过索引引用这些对象(因为迭代器显然不稳定)。
因此,当在indexed_vec
中删除ValueType对象时,必须进行一些内务处理,以保持其他数据结构中的索引是最新的。
因此indexed_vec
也存储了2个lambda,它们是索引更改的有效“订阅者”(观察者模式)。
下面的代码可以正常工作,但是构造indexed_vec
示例的语法似乎有些笨拙。
有更好的选择吗?我调查了演绎指南,但这显然不起作用。
工厂聚会?
(NOTE:将内部向量公开为公共成员的 Package 器不会保持这种状态,这只是为了减少此处的代码)
#include <cstddef>
#include <iostream>
#include <vector>
template <typename ValueType, typename DeleteIndexCBType, typename ChangeIndexCBType>
struct indexed_vec {
indexed_vec(DeleteIndexCBType& dcb_, ChangeIndexCBType& ccb_) : dcb(dcb_), ccb(ccb_) {}
DeleteIndexCBType dcb;
ChangeIndexCBType ccb;
std::vector<ValueType> v;
std::size_t erase(std::size_t index_to_erase) {
// TODO handle empty vector
v[index_to_erase] = v.back();
v.pop_back();
dcb(index_to_erase);
ccb(v.size(), index_to_erase); // NOTE v.size() is NOW one off the end, but that's accurate
return 1;
}
};
template <typename T>
void print(const std::vector<T>& v) {
for (auto& e: v) std::cout << e << " ";
std::cout << '\n';
}
int main() {
std::string context = "captured context";
auto delete_subscriber = [&context](std::size_t idx) {
std::cout << "deleter: " << context << ": " << idx << "\n";
};
auto change_subscriber = [&context](std::size_t old_idx, std::size_t new_idx) {
std::cout << "updater: " << context << ": " << old_idx << " => " << new_idx << "\n";
};
// this seems clumsy?
indexed_vec<std::size_t, decltype(delete_subscriber), decltype(change_subscriber)> v1(
delete_subscriber, change_subscriber);
v1.v.reserve(10);
for (std::size_t v = 10; v != 20; ++v) v1.v.push_back(v);
print(v1.v);
v1.erase(3);
print(v1.v);
}
2条答案
按热度按时间fafcakar1#
简化语法的一个简单方法是将冗长的代码 Package 在工厂函数中,如
使用它可以像下面这样声明
v1
polhcujo2#
由于不能只提供三个模板参数中的 * 一个 *,因此普通的推导指南无法工作,但可以将
ValueType
打包到一个标记中。演绎指南:
用法: