我正在尝试创建一个与C#one类似的Delegate类。
我的目标如下。
void say() { std::cout << "Hello, World!\n" << std::endl; }
int add(int n) { return n + 1; }
[...]
Delegate<void> s(say);
s();
Delegate<int, int> * a = new Delegate<int, int>(add);
我非常接近可以处理正常C函数函数和C ++方法的结果(顺便说一句,我假设是C ++ 11标准)。这就是我的目标。
template <class R, class ...P> class Delegate
{
public:
template <class F, class T> Delegate(F method, T& object)
: handler(MethodDelegate<T, R, P...>(method, object))
{}
template <class T> Delegate(T function)
: handler(FunctionDelegate<R, P...>(function))
{}
virtual ~Delegate() noexcept {}
virtual R run(P... args) const = 0;
inline R operator()(P... args) const
{
return this->run(args...);
}
private:
template <class _T, class _R, class ..._P> class MethodDelegate : public Delegate<_R, _P...>
{
public:
MethodDelegate(_R (_T::*method) (_P...), _T& object)
: object(object), method(method)
{}
virtual ~MethodDelegate() noexcept {}
_R run(_P... args) const
{
return (object.*method)(args...);
}
private:
_T& object;
_R (_T::*method) (_P...);
};
template <class _R, class ..._P> class FunctionDelegate : public Delegate<_R, _P...>
{
public:
FunctionDelegate(_R (*function) (_P...))
: function(function)
{}
virtual ~FunctionDelegate() noexcept {}
_R run(_P... args) const
{
return (*function)(args...);
}
private:
_R (*function) (_P...);
};
Delegate<R, P...> handler;
};
它使用clang++ delegate.cpp --std=c++11
和g++ delegate.cpp --std=c++11
进行编译,但问题出现在我尝试编辑main
时:
int main(int argc, char *argv[])
{
Delegate<void> s(say);
s();
}
Clang ++说:
delegate4.cpp:73:21: error: field has incomplete type 'Delegate<void>'
Delegate<R, P...> handler;
^
delegate4.cpp:109:17: note: in instantiation of template class 'Delegate<void>' requested here
Delegate<void> s(say);
^
delegate4.cpp:18:38: note: definition of 'Delegate<void>' is not complete until the closing '}'
template <class R, class ...P> class Delegate : public Object
^
1 error generated.
我想我需要将FunctionMethod
和DelegateMethod
类的实现移到外面(就像我在分割.h
标题和.cpp
代码时使用常规方法一样)但我可能错了。
感谢您的耐心和帮助,感谢抱歉。
正如@chris在评论中指出的那样,我正在尝试使用同一类型的“原始对象”。一个可能的解决方案是使用指针,但这需要动态分配。有没有办法没有动态分配?
此外,有没有人知道如何做一个名为LambdaDelegate
的第三个类来保持sape层次结构?谢谢:))