【问题标题】:Passing a pointer to a member function as a template argument. Why does this work?将指向成员函数的指针作为模板参数传递。为什么这行得通?
【发布时间】:2010-12-25 08:39:42
【问题描述】:

我有一些代码 100% 适用于我的用例。我只是想知道是否有人可以解释它的工作原理和原因。

我有一个模板类,它位于处理线程和网络通信的一些代码与库用户之间,用于将从服务器接收到的数据传递给用户。

template <class Bar,
          class Baz,
          class BazReturnType,
          void (Bar::*BarSetterFunction)(const BazReturnType &),
          BazReturnType (Baz::*BazGetterFunction)(void) const>
class Foo
{
    Foo( Bar *bar )
        : m_bar(bar)
    {
    }

    void FooMemberFunction( const Baz *baz )
    {
        boost::bind( BarSetterFunction, m_bar,
                     boost::bind( BazGetterFunction, baz )() ) ();
    }

    Bar *m_bar;
};

这个模板根据 Bar 和 Baz 的类型被实例化并在库中使用,如下所示:

typedef Foo<MyBar,
            MyBaz,
            ReturnTypeFromBazGetterFunction,
            &MyBar::ActualSetterFunction,
            &MyBaz::ActualGetterFunction >
    MyFoo;

MyBar *bar = new MyBar;
MyBaz *baz = new MyBaz;
MyFoo *f = new MyFoo( bar );
f->FooMemberFunction( baz );

这一切都有效,boost::bind 调用 getter/setter 函数将数据传递到需要去的地方。 在这种情况下如何以及为什么将指向成员函数的指针作为模板参数传递?


针对 cme​​ts,我没有意识到指向成员函数的指针是有效的模板参数。这不是我以前在“野外”见过的东西。我试过了,它奏效了,但我没想到会这样。

【问题讨论】:

  • 我不确定我是否完全理解您的要求。指向成员的指针是允许的非类型模板参数类型之一。您是否只是在标准中寻找对此的参考? 14.1/4 [templ.param]

标签: c++ templates boost standards


【解决方案1】:

我认为有一个比“因为标准这么说”更好的解释为什么可以这样做:

它起作用的原因是因为指向成员的指针是编译时已知的常量值(指向成员的指针实际上是成员相对于类开头的偏移量)。因此,它们可以用作模板的参数,就像任何其他整数常量一样。

另一方面,普通指针不是编译时常量,因为它们依赖于仅在运行时存在的内存布局。它们不能是模板参数。

【讨论】:

    【解决方案2】:

    当您提出“为什么某物有效?”这样的问题时,这意味着它有效的事实让您有些惊讶。除非您解释为什么您会感到惊讶,否则无法回答这个问题。

    为什么有效?因为语言规范明确表示它应该工作。在您更详细地解释您的担忧之前,没有其他答案。

    【讨论】:

    • 我猜“因为语言规范是这么说的”是答案。根据标准,我没有意识到指向成员函数的指针是有效的模板参数。
    猜你喜欢
    • 1970-01-01
    • 2013-08-11
    • 2012-07-22
    • 2010-11-19
    • 2020-06-09
    • 1970-01-01
    • 2020-10-26
    • 2018-12-07
    • 1970-01-01
    相关资源
    最近更新 更多