我有一个填充字符串向量的实例方法。我试图找到包含特定子字符串的一个向量条目(现在,该子字符串是固定的 - 简单)。
我有.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跟随的例子似乎表明这是相对简单的......所以我做错了什么?
答案 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);