如果我理解正确,std::map和std::unordered_map都会显式存储键(存储键/值对)。是否有其他现成的容器(std、boost或其他广泛实现的容器),它不会存储键,而是允许使用函数从存储的值中派生键(即使用隐式键)?
如果我理解正确,std::map和std::unordered_map都会显式存储键(存储键/值对)。是否有其他现成的容器(std、boost或其他广泛实现的容器),它不会存储键,而是允许使用函数从存储的值中派生键(即使用隐式键)?
使用适当的哈希和/或比较函数为存储值类型选择std::set
或std::unordered_set
。
但是,查找将根据存储值类型而不是键执行,因此您还需要一种方法从键中制造临时对象。
C++库中的所有有序容器,例如std::set
,都允许使用less comparison模板特性,将其作为第二个模板参数传递(在下面的示例中为my_less
)。如果不这样做,operator<
将通过ADL查找并在找到时使用它(如果未找到,则编译错误);对于许多情况来说,这应该是合适的。
您自己的特性或operator<
可以用于根据存储在集合中的数据定义顺序,即无需键。执行此比较不会复制任何数据,请注意它采用const引用。
如果您不想创建堆栈对象,而更喜欢使用堆指针,则可以在标准有序容器中存储boost::shared_ptr
,并相应地编写您的less comparison特性。在这种情况下,您还可以考虑使用boost ptr containers。
示例:
#include <boost/shared_ptr.hpp>
#include <set>
#include <iterator>
#include <iostream>
struct order_by_AB { int a; int b; int c;
order_by_AB(int a, int b, int c) : a(a), b(b), c(c) {}
};
struct my_less
{
bool operator()(const boost::shared_ptr<order_by_AB>& lh, const boost::shared_ptr<order_by_AB>& rh)
{
if (lh->a == rh->a)
return lh->b < rh->b;
return lh->a < rh->a;
}
};
std::ostream& operator<< (std::ostream& os, const boost::shared_ptr<order_by_AB>& rh)
{
os << "(" << rh->a << "," << rh->b << "," << rh->c << ")";
return os;
}
int main()
{
std::set<boost::shared_ptr<order_by_AB>, my_less> data;
data.insert(boost::shared_ptr<order_by_AB>(new order_by_AB(0, 1, 2)));
data.insert(boost::shared_ptr<order_by_AB>(new order_by_AB(2, 3, 2)));
data.insert(boost::shared_ptr<order_by_AB>(new order_by_AB(0, 3, 2)));
data.insert(boost::shared_ptr<order_by_AB>(new order_by_AB(2, 1, 2)));
std::copy(data.begin(), data.end(), std::ostream_iterator<boost::shared_ptr<order_by_AB>>(std::cout, "\n"));
return 0;
}
编辑以提供用户指定的函数对象进行比较的示例。
编辑以在容器中添加boost::shared_ptr
data[x]
,其中 x
不是一个完整的 order_by_AB
对象?因为有时候很难获得一个完整的对象:比如,假设该对象持有某些资源。 - R. Martinho Fernandes