std::map: 仅使用部分keytype进行比较查找
std::map: Use only part of keytype for comparison and finding
我有一个映射,它使用某些数据类型 KT 的 对 作为映射到矩阵类型的键,即 sth。喜欢
std::map<std::pair<KT,KT>, MatType, PairCompare>
为了比较我只需要pair的第一个元素,所以PairCompare非常简单
struct PairCompare
{
bool operator()(const std::pair<KT,KT>& lhs,const std::pair<KT,KT>& rhs) const
{return lhs.first<rhs.first;}
};
但是我想使用整对作为键,因为我在遍历映射时经常需要操作中的第二个元素。
有时候,我也需要只根据单 KT 寻找地图入口。当然我应该在 find() 例程中使用一对 KT,但我想避免创建一对虚拟的 KT,因为我必须多次这样做并且可能变得昂贵。我想使用类似
的东西
std::map<std::pair<KT,KT>, MatType, PairCompare> mymap;
KT mykey = // ... some implementation of KT;
// fill map
auto it = mymap.find(mykey); // <- will not work of course, but what I would like to use
auto it = mymap.find(std::pair<KT,KT>(mykey,mykey)); // <- what I am using so far (creating a dummy pair)
Mykey 通常可以同时是左值和右值(在我的应用程序中)。
有没有什么方法可以定义一种不同类型的密钥,它包含两个 KT 实例并且只使用一个用于地图排序,并且还可以通过 单个 KT 直接查找?可以用一些特殊的比较对象来完成吗?也许还有一种聪明的方法可以绕过使用成对的 KT 作为 Key,但仍然可以在地图迭代中访问第二个 KT?
感谢您的帮助!
P.S.: 准确的说,我用的是KT
typedef std::vector<int> KT
您的问题是您将键视为 "pair of X,Y"。将密钥视为 "an object that supports this and that operations":
template<typename K1, typename K2>
class Key
{
K1 v1_;
boost::optional<K2> v2_;
public:
Key(K1 v1): v1_{ std::move(v1) }, v2_{} {}
Key(K1 v1, K2 v2): v1_{ std::move(v1) }, v2_{ std::move(v2) } {}
bool operator==(const Key<K1,K2>& other)
{
if(!v2_ || !other.v2_)
return v1_ == other.v1_;
return std::tie(v1_, *v2_) == std::tie(other.v1_, *other.v2_);
}
// implement other comparisons, as required
};
using KeyType = Key<int,std::string>;
std::map<KeyType, MatType> YourMap;
// add key comparable by first element:
YourMap[KeyType{0}] = MatType{}; // match KeyType{0, "any string"}
// add key comparable by both elements:
YourMap[KeyType{1, "test"}] = MatType{}; // match KeyType{1, "test"}
在这里尝试强制密钥成对会使问题复杂化。
我有一个映射,它使用某些数据类型 KT 的 对 作为映射到矩阵类型的键,即 sth。喜欢
std::map<std::pair<KT,KT>, MatType, PairCompare>
为了比较我只需要pair的第一个元素,所以PairCompare非常简单
struct PairCompare
{
bool operator()(const std::pair<KT,KT>& lhs,const std::pair<KT,KT>& rhs) const
{return lhs.first<rhs.first;}
};
但是我想使用整对作为键,因为我在遍历映射时经常需要操作中的第二个元素。
有时候,我也需要只根据单 KT 寻找地图入口。当然我应该在 find() 例程中使用一对 KT,但我想避免创建一对虚拟的 KT,因为我必须多次这样做并且可能变得昂贵。我想使用类似
的东西std::map<std::pair<KT,KT>, MatType, PairCompare> mymap;
KT mykey = // ... some implementation of KT;
// fill map
auto it = mymap.find(mykey); // <- will not work of course, but what I would like to use
auto it = mymap.find(std::pair<KT,KT>(mykey,mykey)); // <- what I am using so far (creating a dummy pair)
Mykey 通常可以同时是左值和右值(在我的应用程序中)。
有没有什么方法可以定义一种不同类型的密钥,它包含两个 KT 实例并且只使用一个用于地图排序,并且还可以通过 单个 KT 直接查找?可以用一些特殊的比较对象来完成吗?也许还有一种聪明的方法可以绕过使用成对的 KT 作为 Key,但仍然可以在地图迭代中访问第二个 KT?
感谢您的帮助!
P.S.: 准确的说,我用的是KT
typedef std::vector<int> KT
您的问题是您将键视为 "pair of X,Y"。将密钥视为 "an object that supports this and that operations":
template<typename K1, typename K2>
class Key
{
K1 v1_;
boost::optional<K2> v2_;
public:
Key(K1 v1): v1_{ std::move(v1) }, v2_{} {}
Key(K1 v1, K2 v2): v1_{ std::move(v1) }, v2_{ std::move(v2) } {}
bool operator==(const Key<K1,K2>& other)
{
if(!v2_ || !other.v2_)
return v1_ == other.v1_;
return std::tie(v1_, *v2_) == std::tie(other.v1_, *other.v2_);
}
// implement other comparisons, as required
};
using KeyType = Key<int,std::string>;
std::map<KeyType, MatType> YourMap;
// add key comparable by first element:
YourMap[KeyType{0}] = MatType{}; // match KeyType{0, "any string"}
// add key comparable by both elements:
YourMap[KeyType{1, "test"}] = MatType{}; // match KeyType{1, "test"}
在这里尝试强制密钥成对会使问题复杂化。