【问题标题】:C++ Pointer to Member Function as Template Default ArgumentC++ 指向成员函数的指针作为模板默认参数
【发布时间】:2010-12-15 13:13:48
【问题描述】:

有没有可能,像这样:

template< typename C,
          typename R,
          typename A,
          typename F=R (C::*)(A) >
class MemberFuncPtr { ...

【问题讨论】:

    标签: c++ templates arguments function-pointers


    【解决方案1】:

    是的,它完全有效。

    class X {
    public:
        void Y() {
        }
    };
    
    int main() {
        MemberFuncPtr<X, void, void> func;
    }
    

    构建成功。

    【讨论】:

      【解决方案2】:

      实际上,这对我来说似乎很正确,这段代码我没有收到任何错误:

      template< typename C, 
                typename R, 
                typename A, 
                typename F=R (C::*)(A) > 
      class MemberFuncPtr
      {
              C & Cmember;
              F f;
      public:
              MemberFuncPtr(C & c, F func):Cmember(c), f(func) {}
              R DoIt(A & a)
              {
                      return (Cmember.*f)(a);
              }
      };
      class classA
      {
      public:
              int toInt(double aa)
              {
                      return int(aa);
              }
      };
      int main()
      {
              classA aInstance;
              MemberFuncPtr<classA,int,double> xx(aInstance,&classA::toInt); 
              return 0;
      } 
      

      您可以观察代码here。

      【讨论】:

      • 实际上,在 C++ 中 main() 必须返回整数,因此您的代码并不完全符合标准。此外,MemberFuncPtr::DoIt 的参数必须是左值,这可能有点痛苦。我的小增强版:ideone.com/gA7kJ
      • @Pawel Zubrycki:是的,我忘记了 main(),但是您的版本通过 3 行显而易见的非魔法代码得到了增强?来吧....
      • 这就是为什么我叫它小。
      • @Pawel Zubrycki:那么你的小增强版本与你的MemberFuncPtr::DoIt必须是左值的声明有什么关系吗?
      • @Pawel Zubrycki:main 很特别,不需要明确的return 语句。 3.6.1 [basic.start.main] / 6:如果控制到达main的末尾而没有遇到return语句,则效果是执行return 0;。
      【解决方案3】:

      使用typedef 将使您的代码更加用户友好。只需 typedef 指向函数的指针,然后将其用作其他类型。

      【讨论】:

      • 我想,typedef 不能用于声明模板参数
      • 如何为模板类型编写 typedef ? (好吧,sad_man 已经回复了,不可能)
      • typedef R(C::func*)(A);然后使用 func 作为模板参数。
      • 执行我,我错了。我没有看到 C 也作为模板参数提供。
      【解决方案4】:

      首先你可以编写模板包装器:

      template < typename C >
      class CWrapper
      {
       typedef R(C::func*)(A);
       C* realC;
       Cwrapper(C* c):realC(c){}
      };
      

      然后这样写你的类:

      template < typename C,
                 typename R,
                 typename F = C::func >
      class MemberFuncPtr{...
      

      然后制作MemberFuncPtr&lt; CWrapper &lt;C&gt;, R&gt; memFuncPtr;

      【讨论】:

      • 不会编译 - CWrapper 对 R 和 A 一无所知
      【解决方案5】:

      用一些 C++0x 魔法更正了 Sad_man 的代码:http://ideone.com/rng6V(可能不适合你,因为没有多少编译器有 C++0x :-|)

      适用于右值,并且有示例如何使用 lambda 函数实现您想要的。

      【讨论】:

      • 似乎整个 ideone.com 目前已关闭。
      猜你喜欢
      • 2011-05-25
      • 1970-01-01
      • 1970-01-01
      • 2013-02-15
      • 2011-12-09
      • 2017-10-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多