简体   繁体   English

使用Lower_bound / upper_bound与2种不同类型

[英]using lower_bound/upper_bound with 2 different types

I have a small working code for finding a range of items that uses a special compare method. 我有一个小的工作代码,用于查找使用特殊比较方法的一系列项目。 But when I try to rewrite it with lower_bound() and upper_bound() function, I get a strange error. 但是,当我尝试使用lower_bound()upper_bound()函数重写它时,出现一个奇怪的错误。 I have written a small code to show my problem. 我写了一个小代码来说明我的问题。 Here is the code: 这是代码:

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>

using namespace std;

int main() {
    string str = "banana";
    string keyword = "ana";
    int sa_idx[] = {5, 3, 1, 0, 4, 2};
    vector<int> sa(sa_idx, sa_idx + sizeof(sa_idx) / sizeof(int) );

    auto cmp = [&str] (const int &a, const string &keyword) -> bool
    {
        return strncmp(str.c_str() + a,  keyword.c_str(), keyword.length()) < 0;
    };

    cout << (upper_bound(sa.begin(), sa.end(), keyword, cmp) - 
        lower_bound(sa.begin(), sa.end(), keyword, cmp)) << endl;

    return 0;
}

As you see, compare function uses keyword and value of sa array for compare decision. 如您所见,compare函数使用sa数组的关键字和值进行比较决策。 A standard says: 一个标准说:

The type Type1 must be such that an object of type ForwardIt can be dereferenced and then implicitly converted to Type1. Type1类型必须使得可以取消引用ForwardIt类型的对象,然后将其隐式转换为Type1。 The type Type2 must be such that an object of type T can be implicitly converted to Type2. Type2类型必须使T类型的对象可以隐式转换为Type2。

My compare function has int type for first argument(because of vector<int> of array) and string for the second argument type(as type of keyword). 我的compare函数的第一个参数具有int类型(因为array的vector<int> ),第二个参数类型具有string类型(作为关键字的类型)。 But I don't know why I get following error: 但我不知道为什么会出现以下错误:

In file included from /usr/include/c++/6/bits/stl_algobase.h:71:0,
                 from /usr/include/c++/6/bits/char_traits.h:39,
                 from /usr/include/c++/6/ios:40,
                 from /usr/include/c++/6/ostream:38,
                 from /usr/include/c++/6/iostream:39,
                 from prog.cpp:1:
/usr/include/c++/6/bits/predefined_ops.h: In instantiation of ‘bool __gnu_cxx::__ops::_Val_comp_iter<_Compare>::operator()(_Value&, _Iterator) [with _Value = const std::__cxx11::basic_string<char>; _Iterator = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; _Compare = main()::<lambda(const int&, const string&)>]’:
/usr/include/c++/6/bits/stl_algo.h:2049:14:   required from ‘_ForwardIterator std::__upper_bound(_ForwardIterator, _ForwardIterator, const _Tp&, _Compare) [with _ForwardIterator = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; _Tp = std::__cxx11::basic_string<char>; _Compare = __gnu_cxx::__ops::_Val_comp_iter<main()::<lambda(const int&, const string&)> >]’
/usr/include/c++/6/bits/stl_algo.h:2114:32:   required from ‘_FIter std::upper_bound(_FIter, _FIter, const _Tp&, _Compare) [with _FIter = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; _Tp = std::__cxx11::basic_string<char>; _Compare = main()::<lambda(const int&, const string&)>]’
prog.cpp:19:57:   required from here
/usr/include/c++/6/bits/predefined_ops.h:173:11: error: no match for call to ‘(main()::<lambda(const int&, const string&)>) (const std::__cxx11::basic_string<char>&, int&)’
  { return bool(_M_comp(__val, *__it)); }
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~
prog.cpp:14:61: note: candidate: main()::<lambda(const int&, const string&)>
  auto cmp = [&str] (const int &a, const string &keyword) -> bool
                                                             ^~~~
prog.cpp:14:61: note:   no known conversion for argument 1 from ‘const std::__cxx11::basic_string<char>’ to ‘const int&’

Have I missed something super obvious? 我错过了一些超明显的东西吗? Because it seems compiler looks for string as first argument of compare function. 因为似乎编译器将string作为比较函数的第一个参数。

Your problem here is that std::uppper_bound requires the cmp be of the signature 您的问题在于std::uppper_bound需要cmp为签名

bool(T, decltype(*Iterator))

std::lower_bound has the opposite requirement though and wants std::lower_bound虽然有相反的要求,但想要

bool(decltype(*Iterator), T)

so you can't use the same comparator with both functions. 因此您不能在两个函数中使用相同的比较器。 There are other ways to modify the code but just adding a second comparator like 还有其他方法可以修改代码,但只需添加第二个比较器,例如

auto cmp1 = [&str](const string &keyword, const int &a) -> bool 
{ 
    return strncmp(keyword.c_str(), str.c_str() + a, keyword.length()) < 0;
};
auto cmp2 = [&str] (const int &a, const string &keyword) -> bool
{
    return strncmp(str.c_str() + a,  keyword.c_str(), keyword.length()) < 0;
};

cout << (upper_bound(sa.begin(), sa.end(), keyword, cmp1) - 
    lower_bound(sa.begin(), sa.end(), keyword, cmp2)) << endl;

allows the code to compile. 允许代码进行编译。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM