我想"在我班级中存储会员功能"以后在某些情况下调用它。但我无法修复我的代码来存储带参数的成员函数。 Heres是我的代码:
class IMemFn
{
public:
IMemFn() {}
IMemFn(const IMemFn& other) = delete;
IMemFn& operator=(const IMemFn& other) = delete;
IMemFn(IMemFn&& other) = delete;
IMemFn& operator=(IMemFn&& other) = delete;
virtual ~IMemFn() {}
virtual void func(const std::string& name, const std::string& value) = 0;
};
template<typename ReturnType, class Class>
class MemFn final : public IMemFn
{
public:
typedef ReturnType(Class::*Method)();
MemFn(Class* object, Method method) : IMemFn(), m_object(object), m_method(method) {};
virtual void func(const std::string& name, const std::string& value) override final
{
(m_object->*m_method)(name, value);
};
private:
Class* m_object;
Method m_method;
};
class Test
{
public:
template <class Class, typename Method>
void addMemFn(Class* obj, Method method) {
auto memFn = new MemFn<typename std::result_of<decltype(method)(Class)>::type, Class>(std::forward<Class*>(obj), std::forward<Method>(method));
m_memFns.push_back(memFn);
}
private:
std::list<IMemFn*> m_memFns;
};
class SomeClass
{
public:
void funcAll(const std::string& name, const std::string& value) { std::cout << "SomeClass func"; }
};
class SomeClass2
{
public:
void func2(const std::string& name, const std::string& value) { std::cout << "SomeClass2 func"; }
};
int main()
{
Test test;
SomeClass someClass;
SomeClass2 someClass2;
test.addMemFn(&someClass, &SomeClass ::funcAll);
test.addMemFn(&someClass2, &SomeClass2::func2);
return 0;
}
但编译失败并显示以下消息:'type': is not a member of 'std::result_of<Method (Class)>
并在此行中:(m_object->*m_method)(name, value);
但是如果我尝试保存没有参数的成员函数,那么这个错误就不会出现。
感谢您的帮助!
答案 0 :(得分:1)
这里需要进行一些更改才能进行编译:
首先std::result_of<decltype(method)(Class)
需要std::result_of<Method(Class*,std::string,std::string)
因为它是一个成员函数,它指向this
加上两个参数。
看起来MemFn中的函数inform
应该重命名为func
。
Method
需要添加为MemFn
的模板参数。
然后,您可以通过test
对象调用成员函数,例如:
(*test.m_memFns.begin())->func("a", "b");
但是,在满足界面void IMemFn::func(...)
的同时,您将无法从这些成员函数返回不同类型。
答案 1 :(得分:0)
感谢大家的回答!看起来我很累,因为这些该死的模板。我使用std :: functions和std :: bind,现在一切都很简单轻松。所以,我的最终代码是:
class Test
{
public:
template <class Class, typename Method>
void addMemFn(Class* obj, Method method) {
auto func = std::bind(method, obj, std::placeholders::_1, std::placeholders::_2);
m_funcs.push_back(func);
}
private:
std::list<std::function<void(const std::string&, const std::string&)>> m_funcs;
};
class SomeClass
{
public:
void funcAll(const std::string& name, const std::string& value) { std::cout << "SomeClass func"; }
};
class SomeClass2
{
public:
void func2(const std::string& name, const std::string& value) { std::cout << "SomeClass2 func"; }
};
int main()
{
Test test;
SomeClass someClass;
SomeClass2 someClass2;
test.addMemFn(&someClass, &SomeClass::funcAll);
test.addMemFn(&someClass2, &SomeClass2::func2);
return 0;
}