【发布时间】:2015-10-30 04:26:40
【问题描述】:
假设我有一个字符串向量,我想找到所有以'a' 开头的字符串,所以我可以这样做:
struct cmp {
bool operator()( const std::string &s, char c ) const { return s.front() < c; }
bool operator()( char c, const std::string &s ) const { return s.front() < c; }
};
std::vector<std::string> strings;
...
std::sort( strings.begin(), strings.end() );
auto range = std::equal_range( strings.begin(), strings.end(), 'a', cmp{} );
...
这种方法容易出错,容易出错(比如我认为第二种方法应该是c < s.front())并且有重复代码。
那么是否可以用泛型 lambda 而不是用 2 种方法的结构来实现比较函数?
更一般的问题,为什么要比较的值必须作为参数传递给std::lower_bound、std::upper_bound 和std::equal_range,当它可以很容易地被 lambda 捕获或传递给比较结构时,那么这个问题就不会有吗?
如果std::equal_range 不需要值,它会如何工作?
struct cmp {
cmp( char lc ) : c( lc ) {}
bool operator()( const std::string &s ) const { return s.front() < c; }
char c;
};
std::vector<std::string> strings;
...
std::sort( strings.begin(), strings.end() );
auto range = std::equal_range( strings.begin(), strings.end(), cmp{'a'} );
【问题讨论】:
-
如果你愿意传递
"a"代替'a',那么一个接受两个字符串并比较它们的第一个字符的lambda 将起作用。否则,具有两个重载的命名类对我来说似乎是最干净的解决方案。但请注意,正如目前所写的,第二个重载的比较方式是错误的。 -
@IgorTandetnik 这很明显,但它可能不是字符串,而是一个对象,它按部分排序,所以我不想创建整个对象只是为了将它用作键。跨度>
-
你可以使用
std::partition_point。 -
@T.C.你能提供一个例子作为答案吗?谢谢
标签: c++ lambda c++14 generic-lambda