C++:模板问题 (C2064)

标签 c++ templates syntax stl

我遇到了编译器错误,我不确定原因。我在这里做错了什么:

刽子手.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;
}

实用程序.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>          ]

最佳答案

使用以下代码将绑定(bind)成员函数用作谓词:

return Utils::findAll_if<char>(
                   guesses.begin(), guesses.end(), 
                   std::bind1st(std::mem_fun(&Hangman::isIncorrectGuess), this)));

成员函数需要一个隐式的 this 参数,不能直接与 STL 算法一起使用。因此,上面的代码使用 std::mem_fun 为成员函数生成一个适配器,并使用 std::bind1st 将其绑定(bind)到当前实例。

您可能想查看 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::bind1stboost::bind 您可以生成执行此操作的适配器并实现 operator() 允许它们像普通函数一样被调用。

关于C++:模板问题 (C2064),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2931566/

相关文章:

c++ - 阵列性能问题

javascript - Meteor:如何根据数据库中的值设置单选按钮的值

c++ - 为什么宏扩展遵循模板扩展?

c++ - 模板外的类型名

c - 为什么在 C 结构定义中有一个嵌套指针?

java - setheight() 不改变变量

c++ - 从随机起始位置开始的螺旋阵列

c++ - 具有多态性的 std::bind 和 std::function,基类

c++ - 如何设置 ostream 的指数字段的宽度?

Java "<<"是什么意思?