2016-04-24 44 views
1

所以我试图增加一个功能,比较两个std::string的无视情况从这里:Case insensitive standard string comparison in C++错误当调用std ::等于一个类成员函数作为比较器

#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

确保包含所有必需的标题。你缺少算法,可能还有其他的。 – juanchopanza

+0

这是一个基本事实,即成员函数不能通过与非成员函数相同类型的函数指针来使用。 (它有它自己的,但是它们很明显,并且不能隐式转换,原因很明显。) –

回答

2

您应该使用静态函数作谓语:

static bool icompare_pred(char a, char b) { 
^^^^^^ 

,或者你可以使用拉姆达:

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);}); 
} 
+0

哦,那太快了!谢谢,侦探,案件关闭。 (在6分钟内) – RICHnsk

2

icompare_pred()foo

static bool icompare_pred(char a, char b) { 
// ^^^^^^ 
     return std::tolower(a) == std::tolower(b); 
    } 

静态功能或移动功能作为自由功能的类foo

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 
1

There ar你的代码中有多个错误,其中一些显然没有被你的编译器捕获(由于它的宽容性?)。例如,icompare_pred本身不是有效的C++表达式。非静态成员函数名称本身不构成C++中的有效表达式。您必须使用()运算符调用该函数,或使用&运算符和一个限定名称形成指向该函数的指针。你所要做的就中适当地表示为

​​

无论是&运营商和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

+0

这是非常彻底的!谢谢! – RICHnsk

相关问题