标准库中是否有支持以下用例的部分:您有N个集合,每个集合可能是一种集合类型(C1、C2 ...、Cn),所有集合都支持begin()
、end()
和迭代,即向量、双端队列等。
这些集合中的每一个都可以包含不同类型的对象,即,集合是C1、C2、C3,并且具有不同的大小。
此外,所有这些类型都可以通过时间戳排序,但是每个项存储时间戳的方式不同。例如,类型A有成员A.timestamp
,B有成员B.TimeStamp
,C有函数C.GetTimestamp()
。
每个集合都已通过此函数排序。
我想要做的是使用order函数按顺序迭代所有集合中的所有项,并调用另一个函数,即访问函数,std::function<void(A &)>
用于A的集合,std::function<void(B&)>
用于类型B的项,等等。
然后,我想按时间戳顺序调用每个项目。例如:
class A
{
public:
time_t timeStamp;
int length;
};
class B
{
public:
B(time_t _tm, std::string _name):timestamp(_tm), name(_name){}
time_t GetTimestamp() { return timeStamp; }
std::string GetName() { return name; }
private:
time_t timeStamp;
std::string name;
}
std::vector<A> listA {1, 4}, {5, 7}, {8,9});
std::deque<B> listB { B(0,"bob"), B(3, "Frank") };
// iterate over listA and listB in time sequential order
// for items in A call [](const A&a) { std::cout << a.length << std::endl; }
// for items in B call [](const B&b) { std::cout << b.name << std::endl; }
// Output would be:
// bob
// 4
// Frank
// 7
// 9
我对实现的想法是,定义一个基类,该基类由排序函数返回的类型模板化:
template<classname O>
class VisitedCollection
{
public:
virtual bool end() = 0; // returns if we are at the end of collection
virtual O next_order_measure() = 0; returns an instance of a class that can be used for ordering
virtual void visit();
};
class VisitedCollectionA: VisitedCollection<time_t>
{
public:
VisitedCollectionA(std::vector<A> &&a): items(std::move(a))
{
next_item = items.begin();
}
virtual bool end() override { return next_item == items.end(); }
virtual time_t next_order_meaure() override { return nextItem->timeStamp;}
virtual void visit() override { std::cout << nextItem->length << std::endl;}
private:
std::vector<A> &items;
std::vector<A>::iterator next_item;
}
... similar for class B
... could also add a class C, D, etc
Now I can create a collection of VisitedCollection<time_t>, and add VisitedCollectionA, and VisitedCollectionB. This collection of collections would:
首先查看每个集合中第一个项目的排序函数的返回值。哪个项目的值最小,调用它的访问者函数。然后找到下一个项目的排序值最小的集合。在排序函数的约束下,迭代集合的“集合”中第一个出现的集合。一旦集合到达“end”,它就从迭代中删除。
我正在考虑自己的,但想知道在标准库中是否已经有类似的东西,我甚至可以使visit()成为lambda,这将允许VisitedCollectionA类型成为模板,它接受排序类型和集合类型,这将允许主访问者的创建用类似于
{
VisitedCollection<time_t, std::vector<A>>
(
vecA,
[](){ return next_item->timeStamp; },
[](const A&a) { std::cout << a << std::endl; }
),
VisitedCollection<time_t, std::deque<B>>
(
deqB,
[](){ return next_item->GetTimestamp(); },
[](const B&b) { std::cout << a << std::endl; }
)
}
这感觉有点像变量和范围的混合
有这样的东西吗?
1条答案
按热度按时间gjmwrych1#
在C++ std中没有直接的解决方案(或者其他的std,我猜?),但是不管怎样,在那里可以找到一些对自制解决方案的支持。尽管不是最优的,但是如果需要的话,它应该很容易理解和重写。
首先,你需要const getter(这里省略了)和一个统一的接口来从迭代的类型中获取时间戳:
基本思想是将所有元素的引用放入一个容器中(作为变量),排序然后访问它们:
用法示例:
如果你还没有lambda "重载"结构体,那么就这样做: