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。