C++:模板出现问题 (C2064)
我遇到编译器错误,但我不知道为什么。我在这里做错了什么:
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> ]
I'm having compiler errors, and I'm not sure why. What am I doing wrong here:
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);
}
}
This produces the following compiler errors:
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> ]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用以下代码将绑定成员函数用作谓词:
成员函数需要隐式
this
参数,并且不能直接与 STL 算法一起使用。因此,上面使用 std::mem_fun 为成员函数生成一个适配器,并使用 std::bind1st 将其绑定到当前实例。你可能想看看 Boost.Bind,它使得这些东西更简单:
问题来自于 STL 算法调用谓词等的事实,类似于:
...这对成员函数不起作用。必须使用特殊语法和实例或指向一个实例的指针来调用成员函数指针 - 例如:
参见例如 这篇文章了解有关成员指针的更多信息。使用
std::mem_fun
/std::bind1st
或boost::bind
您可以生成执行此操作的适配器并实现operator(),这使得它们可以像普通函数一样被调用。Use the following to use a bound member function as a predicate:
Member functions expect an implicit
this
parameter and can't be used directly with STL algorithms. Thus the above generates an adapter for the member function by usingstd::mem_fun
and binds it to the current instance usingstd::bind1st
.You might want to look into Boost.Bind, which makes these things easier:
The problem comes from the fact that the STL algorithms call the predicates etc. similar to this:
... which doesn't work for member functions. Member function pointers would have to be invoked using a special syntax and an instance or a pointer to one - e.g.:
See e.g. this article for more on member pointers. Using
std::mem_fun
/std::bind1st
orboost::bind
you can generate adapters that do this and implementoperator()
which allows them to be called similar to common functions.您希望您的谓词是(或表现得像)一个简单的函数,它接受
char
并返回bool
。编译器抱怨&Hangman::isIn CorrectGuess
的类型为bool (__thiscall Hangman::* )(char)
,即 - 它是一个指向非成员的指针静态成员函数。成员函数不能像普通函数一样简单地使用char
参数来调用,因为它需要 Hangman 对象来工作。如果可以使用静态函数,您可以将
isIn CorrectGuess
设为静态,但我猜CorrectAnswer
是 Hangman 的成员,并且谓词需要访问它。在这种情况下,请使用像 Georg 的答案中那样的活页夹。You want Your predicate to be (or behave like) a simple function that takes a
char
and returnsbool
. The compiler complains that&Hangman::isIncorrectGuess
is of typebool (__thiscall Hangman::* )(char)
that is - it's a pointer to member to a non-static member function. Member function can't be simply called withchar
parameter, like a normal function, because it requires an object of Hangman to work on.If it was possible to use a static function You could make
isIncorrectGuess
static but I guess thecorrectAnswer
is a member of Hangman and the predicate needs an access to it. In that case use a binder like in Georg's answer.您需要使用 mem_fun
You need to use mem_fun