C++ 在自定义比较器设置的std::set中查找元素

C++ 在自定义比较器设置的std::set中查找元素,c++,stdset,C++,Stdset,我创建了一个类Route,我想将它存储在std::set中。路由是由Id索引的,所以我想要的是能够有一个类似 class RouteTemplate { Route *RouteTemplate::getRoute(const char *pId); Route::ptr_set mRoutes; }; Route *RouteTemplate::getRoute(const char *pId) { Route::ptr_set::const_iterator pos

我创建了一个类
Route
,我想将它存储在
std::set
中。路由是由Id索引的,所以我想要的是能够有一个类似

class RouteTemplate
{
    Route *RouteTemplate::getRoute(const char *pId);
    Route::ptr_set mRoutes;
};

Route *RouteTemplate::getRoute(const char *pId)
{
    Route::ptr_set::const_iterator pos = mRoutes.find(pId);
    if(pos == mRoutes.end())
        return NULL;

    return *pos;
}
但是我得到了一个编译器错误

conversion from 'const char *' to 'Route *const ' not possible
据我所知,我必须实现比较器,我做到了

class Route
{
public:
    static const size_t _id_len = 11;

    class comparator
    {
    public:
        bool operator() (const Route &oLeft, const Route &oRight) const
        {
            return oLeft < oRight;
        }
    };
    class ptr_comparator
    {
    public:
        bool operator() (const Route *oLeft, const Route *oRight) const
        {
            return (*oLeft) < (*oRight);
        }
    };

    typedef std::set<Route, Route::comparator> set;
    typedef std::set<Route *, Route::ptr_comparator> ptr_set;

public:
    Route(void);
    Route(const char *oId);
    virtual ~Route(void) {};

    inline bool operator<(const Route &oOther) const
    {
        return strncmp(mId, oOther.mId, _id_len) < 0;
    }

    inline bool operator<(const char *oId) const
    {
        if(!oId)
            return false;

        return strncmp(mId, oId, _id_len) < 0;
    }

    inline const char *getId(void) const { return mId; }
    inline void setId(const char *oId)
    {
        if(oId == NULL)
            mId[0] = 0;
        else
        {
            strncpy(mId, oId, sizeof(mId));
            mId[_id_len] = 0;
        }
    }

private:
    char mId[_id_len+1];
    // Additional members
};
类路由
{
公众:
静态常量大小\u t\u id\u len=11;
类比较器
{
公众:
布尔运算符()(常数路由和oLeft、常数路由和oRight)常数
{
返回油量内联bool操作符我假设您希望利用C++14中添加的
模板
d重载。在此之前,您只能
查找
键类型的键,该键用于
std::set
。因此,首先要做的是使用C++14编译器

第二,只有当生成的比较具有与构造(临时)相同的语义时,额外的重载才能起作用键,并将其与
std::set
s比较器进行比较。如果我没有遗漏任何内容,您的比较器将符合此条件。但是,为了避免意外错误,您必须明确确认,通过为类型指定类型成员
是透明的

如果你可以接受一个临时文件的创建,你可以明确地要求它。这应该是可行的

Route *RouteTemplate::getRoute(const char *pId)
{
    Route temporary_key {pId};
    Route::ptr_set::const_iterator pos = mRoutes.find(&temporary_key);
    if(pos == mRoutes.end())
        return NULL;
    return *pos;
}

您还可以重载
操作符&
,以允许在临时对象上调用它。这将简化
查找
方法的使用,因为您可以动态创建
路由
对象,然后在此临时对象上应用
操作符&

class Route
{
public:
...
    Route* operator&() { return this; }
...
}
然后可以编写
getRoute()
方法,如:

Route *RouteTemplate::getRoute(const char *pId)
{
    Route::ptr_set::const_iterator pos = mRoutes.find(&Route(pId));
    if (pos == mRoutes.end())
        return NULL;

    return *pos;
}

…但问题是什么?!@Biffen:
如果
将是
O(n)
,那么它理论上可以在
O(logn)
@Jarod42中完成。这就是问题所在吗?@Jarod42你认为它可以在log(n)中完成吗?如果按一个比较器对集合进行排序,并按另一个比较器搜索项目?我没有C++14编译器。目前我使用的Visual Studio 2010是关于C++11的(不完全).因此,如果我理解您的评论,这将不起作用,因为编译器中缺少该函数性?但即使如此,构造函数是否应该确保比较仍然有效?它至少对非指针版本有效。您可以从
常量字符[]
构建临时
路由
(您为此转换编写了构造函数)。但您不能从
常量字符*
构建临时
路由*
。就Visual Studio而言,我不知道他们是否支持此功能,但此功能是由其一名维护人员提出的,因此您可能有机会提前采用它。您必须查阅您的文档。正式介绍在C++14。我也试过了,但后来出现了不同的编译器错误。我尝试创建一个SSCE。