我遇到编译错误,我不知道为什么。我在这做错了什么:
Hangman.cpp:
set<char> Hangman::incorrectGuesses()
{
// Hangman line 103
return Utils::findAll_if<char>(guesses.begin(), guesses.end(), &Hangman::isIncorrectGuess);
}
bool Hangman::isIncorrectGuess(char c)
{
return correctAnswer.find(c) == string::npos;
}
Utils.h:
namespace Utils
{
void PrintLine(const string& line, int tabLevel = 0);
string getTabs(int tabLevel);
template<class result_t, class Predicate>
std::set<result_t> findAll_if(typename std::set<result_t>::iterator begin, typename std::set<result_t>::iterator end, Predicate pred)
{
std::set<result_t> result;
// utils line 16
return detail::findAll_if_rec<result_t>(begin, end, pred, result);
}
}
namespace detail
{
template<class result_t, class Predicate>
std::set<result_t> findAll_if_rec(typename std::set<result_t>::iterator begin, typename std::set<result_t>::iterator end, Predicate pred, std::set<result_t> result)
{
// utils line 25
typename std::set<result_t>::iterator nextResultElem = find_if(begin, end, pred);
if (nextResultElem == end)
{
return result;
}
result.insert(*nextResultElem);
return findAll_if_rec(++nextResultElem, end, pred, result);
}
}
这会产生以下编译器错误:
algorithm(83): error C2064: term does not evaluate to a function taking 1 arguments
algorithm(95) : see reference to function template instantiation '_InIt std::_Find_if<std::_Tree_unchecked_const_iterator<_Mytree>,_Pr>(_InIt,_InIt,_Pr)' being compiled
1> with
1> [
1> _InIt=std::_Tree_unchecked_const_iterator<std::_Tree_val<std::_Tset_traits<char,std::less<char>,std::allocator<char>,false>>>,
1> _Mytree=std::_Tree_val<std::_Tset_traits<char,std::less<char>,std::allocator<char>,false>>,
1> _Pr=bool (__thiscall Hangman::* )(char)
1> ]
utils.h(25) : see reference to function template instantiation '_InIt std::find_if<std::_Tree_const_iterator<_Mytree>,Predicate>(_InIt,_InIt,_Pr)' being compiled
1> with
1> [
1> _InIt=std::_Tree_const_iterator<std::_Tree_val<std::_Tset_traits<char,std::less<char>,std::allocator<char>,false>>>,
1> _Mytree=std::_Tree_val<std::_Tset_traits<char,std::less<char>,std::allocator<char>,false>>,
1> Predicate=bool (__thiscall Hangman::* )(char),
1> _Pr=bool (__thiscall Hangman::* )(char)
1> ]
utils.h(16) : see reference to function template instantiation 'std::set<_Kty> detail::findAll_if_rec<result_t,Predicate>(std::_Tree_const_iterator<_Mytree>,std::_Tree_const_iterator<_Mytree>,Predicate,std::set<_Kty>)' being compiled
1> with
1> [
1> _Kty=char,
1> result_t=char,
1> Predicate=bool (__thiscall Hangman::* )(char),
1> _Mytree=std::_Tree_val<std::_Tset_traits<char,std::less<char>,std::allocator<char>,false>>
1> ]
hangman.cpp(103) : see reference to function template instantiation 'std::set<_Kty> Utils::findAll_if<char,bool(__thiscall Hangman::* )(char)>(std::_Tree_const_iterator<_Mytree>,std::_Tree_const_iterator<_Mytree>,Predicate)' being compiled
1> with
1> [
1> _Kty=char,
1> _Mytree=std::_Tree_val<std::_Tset_traits<char,std::less<char>,std::allocator<char>,false>>,
1> Predicate=bool (__thiscall Hangman::* )(char)
1> ]
答案 0 :(得分:3)
使用以下命令将绑定成员函数用作谓词:
return Utils::findAll_if<char>(
guesses.begin(), guesses.end(),
std::bind1st(std::mem_fun(&Hangman::isIncorrectGuess), this)));
成员函数需要隐式this
参数,不能直接与STL算法一起使用。因此,上面使用std::mem_fun
为成员函数生成适配器,并使用std::bind1st
将其绑定到当前实例。
您可能需要查看Boost.Bind,这会让这些变得更容易:
return Utils::findAll_if<char>(
guesses.begin(), guesses.end(),
boost::bind(&Hangman::isIncorrectGuess, this, _1));
问题来自于STL算法调用谓词等事实,类似于:
predicate(someParameter);
...这对成员函数不起作用。必须使用特殊语法和实例或指向一个的指针来调用成员函数指针 - 例如:
(pointerToInstance->*predicate)(someParameter);
参见例如this article了解有关成员指针的更多信息。使用std::mem_fun
/ std::bind1st
或boost::bind
,您可以生成执行此操作的适配器并实现operator()
,从而允许它们被调用,类似于常用功能。
答案 1 :(得分:1)
您希望您的谓词是(或表现得像)一个简单的函数,它接受char
并返回bool
。编译器抱怨&Hangman::isIncorrectGuess
类型为bool (__thiscall Hangman::* )(char)
,它是指向非静态成员函数的成员的指针。使用char
参数不能简单地调用成员函数,就像普通函数一样,因为它需要一个Hangman对象来处理。
如果可以使用静态函数你可以使isIncorrectGuess
静态但我想correctAnswer
是Hangman的成员,而谓词需要访问它。在这种情况下,请使用像Georg的回答中的粘合剂。
答案 2 :(得分:0)
您需要使用mem_fun
#include <functional>
// ...
set<char> Hangman::incorrectGuesses()
{
return Utils::findAll_if<char>(guesses.begin(), guesses.end(),
std::mem_fun(&Hangman::isIncorrectGuess));
}