所以我试图在一个类中添加一个函数来比较两个std::string
,忽略这里的情况:Case insensitive standard string comparison in C++。
#include <iostream>
#include <string>
using namespace std;
class foo {
public:
bool icompare_pred(char a, char b) {
return std::tolower(a) == std::tolower(b);
}
bool icompare( string a, string b){
return equal( a.begin(), a.end(), b.begin(), icompare_pred);
}
};
int main() {
}
代码没有编译,甚至更多:它将我发送到STL的深度并出现错误
[Error] must use '.*' or '->*' to call pointer-to-member function in '__binary_pred (...)', e.g. '(... ->* __binary_pred) (...)'
在这部分
stl_algobase.h
template<typename _IIter1, typename _IIter2, typename _BinaryPredicate>
inline bool
equal(_IIter1 __first1, _IIter1 __last1,
_IIter2 __first2, _BinaryPredicate __binary_pred)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_IIter1>)
__glibcxx_function_requires(_InputIteratorConcept<_IIter2>)
__glibcxx_requires_valid_range(__first1, __last1);
for (; __first1 != __last1; ++__first1, ++__first2)
if (!bool(__binary_pred(*__first1, *__first2)))
return false;
return true;
}
好吧,我该怎么办?如何解决此错误?
答案 0 :(得分:2)
你应该使用静态函数作为谓词:
static bool icompare_pred(char a, char b) {
^^^^^^
或者您可以使用lambda:
bool icompare( string a, string b){
return equal( a.begin(), a.end(), b.begin(),
[](char a, char b){return std::tolower(a) == std::tolower(b);});
}
答案 1 :(得分:2)
使icompare_pred()
成为foo
static bool icompare_pred(char a, char b) {
// ^^^^^^
return std::tolower(a) == std::tolower(b);
}
或将该函数移出类foo
作为自由函数。
答案 2 :(得分:1)
您需要比较器为static
static bool icompare_pred(char a, char b) {
return std::tolower(a) == std::tolower(b);
}
此外,由于icompare
不是静态的,您必须从foo
实例调用它,就像这样
int main()
{
foo f;
std::cout << f.icompare("TEST", "test");
}
Live demo,输出
1
答案 3 :(得分:1)
您的代码中存在多个错误,其中一些错误显然未被编译器捕获(由于其允许性?)。例如,icompare_pred
本身不是有效的C ++表达式。非静态成员函数名本身不会在C ++中形成有效的表达式。您必须使用()
运算符调用该函数,或使用&
运算符和限定名称形成指向它的指针。您要做的事情将正确表达为
bool icompare( string a, string b){
return equal( a.begin(), a.end(), b.begin(), &foo::icompare_pred);
}
&
运算符和foo::
前缀都是必需的。
这就是我们遇到第二个错误的地方。双参数非静态成员函数实际上具有三个参数:您明确声明的两个参数和一个隐式this
参数。因此,在您的代码中,您传递的是三参数函数,其中需要一个双参数函数。这是“解释”此错误的一种方法。
为了使您的成员函数可用作std::equal
的谓词,您可以“绑定”隐式this
参数 - 将特定的固定值附加到它 - 从而将三参数函数转换为一个双参数的。例如
bool icompare( string a, string b){
return equal( a.begin(), a.end(), b.begin(),
std::bind(&foo::icompare_pred, this,
std::placeholders::_1, std::placeholders::_2));
}
这应该按照预期编译和工作。
但是,由于您的比较谓词并不真正需要或关心该隐式this
参数,更好的方法是完全摆脱它:只需将比较器声明为static
,如建议的那样在其他答案。如果您这样做,&foo::icompare_pred
语法也将变得不必要,您将能够像原始代码一样使用icompare_pred
。