【发布时间】:2014-10-16 16:30:54
【问题描述】:
有没有办法让编译器从方法的签名中推断出模板参数?
我有这门课,基于文章The Impossibly Fast C++ Delegates。
template<typename... Ds>
class Delegate {
public:
Delegate()
: object_ptr(0)
, stub_ptr(0)
{}
template <class T, void (T::*TMethod)(Ds...)>
static Delegate from_member(T* object_ptr)
{
Delegate d;
d.object_ptr = object_ptr;
d.stub_ptr = &method_stub<T, TMethod>; // #1
return d;
}
void operator()(Ds... ds) const
{
return (*stub_ptr)(object_ptr, ds...);
}
private:
typedef void (*stub_type)(void* object_ptr, Ds...);
void* object_ptr;
stub_type stub_ptr;
template <class T, void (T::*TMethod)(Ds...)>
static void method_stub(void* object_ptr, Ds... ds)
{
T* p = static_cast<T*>(object_ptr);
return (p->*TMethod)(ds...); // #2
}
};
要实例化这个类,可以说
struct Foo {
void foo(int x, double y) {
std::cout << "foo(" << x << ", " << y << ")" << std::endl;
}
};
int main() {
Foo f;
auto d = Delegate<int, double>::from_member<Foo, &Foo::foo>(&f);
d(1, 2.3);
}
我的问题是:有没有办法让编译器从方法本身推断方法参数类型?也就是说,我可以避免在创建委托时指定<int, double>,并让编译器为我解决这个问题吗?我希望能够按照DelegateFactory::from_member<Foo, &Foo::foo>(&f) 的方式说些什么。
【问题讨论】:
-
你为什么不简单地使用 C++11 lambas 或
std::function?你读到的那篇文章是 9 岁,也就是永恒。 -
@Walter 简短的回答只是学术兴趣——我在玩这个想法,但不知道如何实现这一点。这篇文章仍然是相关的 - 在这里查看一些讨论:stackoverflow.com/q/11126238/31455
-
您可能希望重载它以与
const成员函数一起使用,即template<class T, void (T::*TMethod)(Ds...) const>。如果你真的想彻底,volatile和const volatile,不像任何人都使用过这些。 -
我不相信这是链接问题的重复 - 我不是在这里问如何确定函数的参数,而是让它们隐含。