Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 映射:仅使用部分键类型进行比较和查找_C++_C++11_Dictionary_Stl - Fatal编程技术网

C++ 映射:仅使用部分键类型进行比较和查找

C++ 映射:仅使用部分键类型进行比较和查找,c++,c++11,dictionary,stl,C++,C++11,Dictionary,Stl,我有一个映射,它使用一些数据类型KT的对作为键映射到矩阵类型,例如 std::map<std::pair<KT,KT>, MatType, PairCompare> std::map 为了进行比较,我只需要配对中的第一个元素,因此PairCompare非常简单 struct PairCompare { bool operator()(const std::pair<KT,KT>& lhs,const std::pair<KT,KT&g

我有一个映射,它使用一些数据类型KT的对作为键映射到矩阵类型,例如

std::map<std::pair<KT,KT>, MatType, PairCompare>
std::map
为了进行比较,我只需要配对中的第一个元素,因此PairCompare非常简单

struct PairCompare
{
    bool operator()(const std::pair<KT,KT>& lhs,const std::pair<KT,KT>& rhs) const
    {return lhs.first<rhs.first;}
};
struct PairCompare
{
布尔运算符()(常数std::pair&lhs,常数std::pair&rhs)常数

{return lhs。首先您的问题是您将密钥视为“X,Y对”。将密钥视为“支持这个和那个操作的对象”:

模板
类密钥
{
K1 v1;
boost::可选v2;
公众:
键(k1v1):v1{std::move(v1)},v2{}}
键(k1v1,k2v2):v1{std::move(v1)},v2{std::move(v2)}{
布尔运算符==(常量键和其他)
{
如果(!v2| | |!其他.v2|)
返回v1_==other.v1;
返回std::tie(v1_u,*v2_u)=std::tie(other.v1_u,*other.v2_u);
}
//根据需要执行其他比较
};
使用KeyType=Key;
映射你的地图;
//添加按第一个元素比较的键:
YourMap[KeyType{0}]=MatType{};//匹配KeyType{0,“任意字符串”}
//添加两个元素可比较的键:
YourMap[KeyType{1,“test”}]=MatType{};//匹配KeyType{1,“test”}

试图将密钥强制为一对会使问题复杂化。

“这可能会变得昂贵”。您是否测量到它对于您的用例来说太慢了?这不是非常糟糕,但它确实增加了我想消除的开销。当然,当KT是相当长的向量(如10左右)时,它更为明显.但是…如果该对的第二部分不用于比较,则表示键1(A,B)和键2(A,C)相同(关于比较)…而不是表示只有键1或键2可以在地图中…因此可以使用(A,X)要查询映射…并添加一个附加步骤来检查密钥是否符合您的预期。可能是您确实想要一个
std::map
?看起来您定义了一对作为密钥,然后尝试以某种方式撤消该定义,并将密钥视为仅一个元素。
std::map
必须是最小的本地对象版本。有两个向量作为键迫使每个比较操作需要大量的内存查找,许多潜在的缓存未命中。这将是我对OP的建议。非常好。这是一个非常有趣的解决方案!事实上,我想从包含另一个KT的KT中定义一些派生类,但使用
boost::OP(我不知道)当然更好!
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)
typedef std::vector<int> KT
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"}