【问题标题】:Infer template from method parameters [duplicate]从方法参数推断模板[重复]
【发布时间】: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);
}

我的问题是:有没有办法让编译器从方法本身推断方法参数类型?也就是说,我可以避免在创建委托时指定&lt;int, double&gt;,并让编译器为我解决这个问题吗?我希望能够按照DelegateFactory::from_member&lt;Foo, &amp;Foo::foo&gt;(&amp;f) 的方式说些什么。

【问题讨论】:

  • 你为什么不简单地使用 C++11 lambas 或std::function?你读到的那篇文章是 9 岁,也就是永恒。
  • @Walter 简短的回答只是学术兴趣——我在玩这个想法,但不知道如何实现这一点。这篇文章仍然是相关的 - 在这里查看一些讨论:stackoverflow.com/q/11126238/31455
  • 您可能希望重载它以与const 成员函数一起使用,即template&lt;class T, void (T::*TMethod)(Ds...) const&gt;。如果你真的想彻底,volatileconst volatile,不像任何人都使用过这些。
  • 我不相信这是链接问题的重复 - 我不是在这里问如何确定函数的参数,而是让它们隐含。

标签: c++ c++11


【解决方案1】:
#include <iostream>

template <typename... T>
class Delegate
{
};

template <typename T, typename... Args>
Delegate<Args...> from_member(T* t, void (T::*)(Args...))
{
    return Delegate<Args...>(/* fill in, you have all data you need */);
}

struct Foo
{
    void foo(int x, double y)
    {
        std::cout << "foo(" << x << ", " << y << ")" << std::endl;
    }
};

int main()
{
    Foo f;
    auto d = from_member(&f, &Foo::foo);

    return 0;
}

【讨论】:

  • 您可以将这些重载替换为对参数使用参数包的重载。
  • @0x499602d2:感谢您指出这一点
猜你喜欢
  • 1970-01-01
  • 2013-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多