在实例方法中使用find_if

时间:2012-04-23 13:46:50

标签: c++ visual-studio visual-studio-2010 visual-c++

我有一个填充字符串向量的实例方法。我试图找到包含特定子字符串的一个向量条目(现在,该子字符串是固定的 - 简单)。

我有.h

namespace Data
{
namespace Shared
{

    class Logger
    {
      public:
        bool FindLogDirectoryPredicate(const string &str);
        int GetLogDirectory(string logConfigFile, string& logDirectory);
...
    }
}
}

.cpp

#include <algorithm>
#include <vector>
#include "Logger.h"

bool Logger::FindLogDirectoryPredicate(const string &str) 
{
    // Return false if string found.
    return str.find("File=") > 0 ? false : true;
}

int Logger::GetLogDirectory(string logConfigFile, string& logDirectory)
{
    vector<string> fileContents;
    ...
    vector<string>::iterator result = find_if(fileContents.begin(), fileContents.end(), FindLogDirectoryPredicate);
    ...
}

在Visual Studio 2010中对此进行编译,我收到:

Error   7   error C3867: 'Data::Shared::Logger::FindLogDirectoryPredicate': function call missing argument list; use '&Data::Shared::Logger::FindLogDirectoryPredicate' to create a pointer to member   Logger.cpp  317 1   Portability

投掷&amp;在find_if调用中的函数ref前面,然后得到:

Error   7   error C2276: '&' : illegal operation on bound member function expression    Logger.cpp  317 1   Portability

我确实尝试将谓词函数放在类之外,但这似乎不起作用 - 给了我一个函数找不到错误。尝试使用类名限定谓词...这给了我一个不同的算法错误(标题):

Error   1   error C2064: term does not evaluate to a function taking 1 arguments    c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\algorithm    83  1   Portability

我从here跟随的例子似乎表明这是相对简单的......所以我做错了什么?

3 个答案:

答案 0 :(得分:4)

问题是FindLogDirectoryPredicate是一个实例方法:指定它的名称是不够的,你不得不指定哪个对象该方法应该是拜访。现在,这个问题的答案对我们来说是显而易见的(this),而不是编译器。

执行此操作的经典方法是使用

find_if(fileContents.begin(), 
        fileContents.end(), 
        bind1st(mem_fun(&Logger::FindLogDirectoryPredicate), this));

这里发生了什么?

mem_fun“将成员函数转换为函数对象”。也就是说,它创建了一个类型的实例(未指定的类型,但我们不关心)暴露operator()(这是我们关心的!)。此运算符期望第一个参数是指向定义成员函数的类型实例的指针;在这里,这将是Logger的实例。

bind1st然后接受这个带有两个参数的函数对象(第一个是指向实例的指针,第二个是原始的const string &参数)并返回一个只带一个参数的不同函数对象({ {1}})。另一个参数固定为const string &的第二个参数(bind1st)的值。

或者,如果您可以this FindLogDirectoryPredicate,那么就不再需要指定要调用它的实例,因此问题会自动消失。

答案 1 :(得分:3)

制作谓词static

class Logger
{
  public:
    static bool FindLogDirectoryPredicate(const string &str);
}

或许,使用lambda。

result = std::find_if(begin(), end(), [&this] (const std::string& s) 
     { return FindLogDirectoryPredicate(s); } );

如果必须使用C ++ 98 / C ++ 03,也可以使用std :: mem_fun(以及相关的<functional>内容)

result = std::find_if(begin(), end(), 
     std::bind1st(std::mem_fun(&Logger::FindLogDirectoryPredicate), this) );

答案 2 :(得分:0)

使您的谓词成为静态类成员。

static bool FindLogDirectoryPredicate(const string &str);