我正在尝试创建以下类,我可以使用它来测试对象,看看它们是否通过了一些过滤器。
template <typename T>
class Filter
{
public:
typedef bool (*Functor)(const T&);
bool test(const T& t) {
return func(t);
}
void setTester(Functor f) {
func = f;
}
private:
Functor func;
};
如果我只是在全局命名空间中创建一个方法,这可以正常工作。
bool testFunc(const Object& obj)
{
return !obj.name().isEmpty();
}
void foo(const Object& obj)
{
Filter<Object> filter;
filter.setTester(testFunc);
filter.test(obj);
}
但我真正喜欢的是使用lambda函数,这样我就不必像这样创建所有的过滤方法了。我希望能够即时创建它们。
void foo(const Object& object)
{
Filter<Object> filter;
filter.setTester([](const Object& object) {
return !object.name().isEmpty();
});
filter.test(object);
}
但是当我这样做时,我得到以下编译错误。
C2664: 'ov::Filter<T>::setTester' : cannot convert parameter 1 from 'ov::`anonymous-namespace'::<lambda0>' to 'bool (__cdecl *)(const T &)'
with
[
T=ov::Object
]
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
我已经阅读过关于将lambda函数作为函数指针传递的其他帖子,例如this one,我知道他们无法捕获它们才能使其工作。那没关系,你可以看到我不想捕捉任何东西。
我正在使用VS2010编译我的代码。
那么我做错了什么?
答案 0 :(得分:1)
这对我来说很好,但假设类Object实际上是在某处定义的,成员名称()返回一个字符串,在这种情况下我使用public void setRunMode()
{
// _solution_path, _solution_name must be replaced by your solution path and solution name
Type t = System.Type.GetTypeFromProgID("VisualStudio.DTE.10.0");
EnvDTE80.DTE2 dte2 = (EnvDTE80.DTE2)System.Activator.CreateInstance(t);
dte2.MainWindow.Visible = false; //keep TwinCAT window closed
Solution4 solution4 = (Solution4)dte2.Solution;
EnvDTE.Project project = null;
solution4.Open(Path.Combine(_solution_path, _solution_name + ".sln").ToString());
project = (EnvDTE.Project)solution4.Projects.Item(1);
ITcSysManager5 sysmanager5 = (ITcSysManager5)project.Object;
sysmanager5.StartRestartTwinCAT();
dte2.Quit();
}
而不是public void setRunMode()
{
TcAdsClient client = new TcAdsClient();
StateInfo mode = new StateInfo();
client.Connect((int)AmsPort.SystemService);
mode.AdsState = client.ReadState().AdsState;
mode.AdsState = AdsState.Reset;
client.WriteControl(mode);
client.Dispose();
}
。
我成功测试了以下代码:
empty()
输出:1
p.s:我正在使用VS2015。
答案 1 :(得分:1)
您的编译器可能不支持此功能。你正在使用MS,所以很多这些东西都会丢失。他们在最近的那些中获得了最重要的东西,但是回过头来一点也没多少。我不认为他们现在支持这个。
答案 2 :(得分:1)
如果明确设置输出类型会发生什么?
filter.setTester([](const Object& object) -> bool {
return !object.name().isEmpty();
});