【问题标题】:Calling pointer-to-member function in call for a function passed to a template function在调用传递给模板函数的函数时调用指向成员函数的指针
【发布时间】:2010-12-23 09:40:20
【问题描述】:

这是我正在尝试使用的提供的函数模板:

template <class Process, class BTNode>
void postorder(Process f, BTNode* node_ptr)
{
   if (node_ptr != 0)
   {
      postorder( f, node_ptr->left() );
      postorder( f, node_ptr->right() );
      f( node_ptr->data() );
   }
}

这是我的调用,我传递的函数:

void city_db::print_bst() {
   postorder(&city_db::print, head);
}

void city_db::print(city_record target)
{
   std::cout << target.get_code();
}

这是我得到的编译时 (G++) 错误:

CityDb.cpp:85: 实例化自 这里

BinTree.template:80: 错误:必须使用 '.' 或 '->' 来调用 'f 中的指向成员函数的指针 (...)’

make: *** [CityDb.o] 错误 1

这是对函数模板中f( node_ptr-&gt;data() );行的引用。

这是针对数据结构项目的。赋值被修改了,所以我们不需要将函数传递给函数,但是我对这个感兴趣已经有一段时间了,我觉得我几乎在这里。我已经用尽了 Google 和 Lab TA,所以如果 StackOverflow 有想法,他们将不胜感激。

【问题讨论】:

    标签: c++ templates pointers function-pointers argument-passing


    【解决方案1】:

    您的问题是 postorder 接受必须以这种方式调用的函数对象:

    f(arg);
    

    您正在传递一个指向成员函数的指针。您应该首先调用 mem_fun 从指向成员的指针中创建一个函数对象:

    std::mem_fun(&city_db::print)
    

    返回的函数对象有两个参数:指向 city_db 的指针(隐式 this 指针)和要打印的对象。您可以使用 bind1st 将第一个绑定到 this,如下所示:

    std::bind1st(std::mem_fun(&city_db::print), this)
    

    现在你应该可以调用 postorder 了:

    postorder(std::bind1st(std::mem_fun(&city_db::print), this), head);
    

    【讨论】:

    • 我花了几分钟才明白这一点,但一旦点击它就很有意义了。感谢您将其分解为可管理的部分。最后一行解决了构建错误。
    【解决方案2】:

    您需要一个city_db 的实例来调用print

    您传递的是一个指向成员函数的指针(将其视为 vtable 中的一个槽),但您也需要一个 this 指针。您可以将其作为另一个参数传递给 postorder 函数。

    template <class Object, class Process, class BTNode>
    void postorder(Object* obj, Process f, BTNode* node_ptr)
    {
       if (node_ptr != 0)
       {
          postorder(obj, f, node_ptr->left() );
          postorder(obj, f, node_ptr->right() );
          ((obj)->*(f))( node_ptr->data() );
       }
    }
    

    C++ FAQ Lite

    【讨论】:

    • parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.5 常见问题解答的这一部分提供了一些有用的指示,以使语法更简洁。总的来说,我更喜欢 Thomas 的回答。
    • 虽然我可能会修改它,但我将 BinTree 视为一个无需修改的大型库。不过,这是对下面发生的事情的一个很好的了解,感谢您提供的资源,添加到美味中以在我下次遇到问题时检查。
    【解决方案3】:

    您需要将 city_db::print() 设为静态或提供 city_db 对象。

    【讨论】:

      【解决方案4】:

      写的

      void city_db::print(city_record target)
      {
         std::cout << target.get_code();
      }
      

      不依赖于类状态。将其声明为静态函数,编译器将不需要this 指针来调用它。 FAQ 正题。

      【讨论】:

      • 虽然这个例子确实如此,但它回避了指向成员函数的指针的整个问题。
      猜你喜欢
      • 1970-01-01
      • 2023-03-28
      • 2018-12-07
      • 1970-01-01
      • 2012-12-16
      • 1970-01-01
      • 2010-09-13
      • 2017-05-16
      • 1970-01-01
      相关资源
      最近更新 更多