【问题标题】:C++ Passing a member function of a template class to another functionC ++将模板类的成员函数传递给另一个函数
【发布时间】:2026-02-23 17:55:02
【问题描述】:

这适用于非成员函数。如何更改它以能够使用成员函数执行相同的操作。我尝试过“函数指针”技术,但在性能方面效率不高。

template <typename Func>
int f(int a, Func somefunc) {
  somefunc(a);
  return 0;
}
...
f(5,myfoo);

我希望能够做到这一点:

int myClass::mybar() {    
  f(5,myfoo); //where myfoo is actually "myClass::myfoo" here. 
              //I want myClass to be the template class. 
}

如何定义模板类并使其成员函数模板也一样,以便f 可以与任何类和任何成员函数一起使用?

谢谢!

【问题讨论】:

  • 你说的这种“函数指针”技术是什么?
  • 您是否尝试使用该类的另一个模板参数重载您的函数?那么函数的类型将是 Class::Func
  • @BrianBi 我的意思是 C++ 中的函数指针!比如传递函数的地址
  • @Geoffroy:如果你的意思是模板 ,我已经试过了。然后我使用了 Class::Func 而不是 Func。没用!
  • 在 C++ 中使用函数指针很少是合理的,它们通常用作 C++ 和 C 库之间的桥梁,有时也用作“优化”。 C++ 拥有比函数指针更复杂的工具。

标签: c++ templates functor member-functions typename


【解决方案1】:

等等……锤子时间

你的意思是做这样的事情??

#include <stdio.h>
#include <string>
#include <iostream>

void my_int_func(int x)
{
    printf( "%d\n", x );
}

void my_string_func(std::string x)
{
    std::cout << x << std::endl;
}

template <typename type, typename Func>
int f(type a, Func somefunc) {
  somefunc(a);
  return 0;
}

int main()
{
    void (*foo)(int);
    void (*bar)(std::string);
    /* the ampersand is actually optional */
    foo = &my_int_func;
    bar = &my_string_func;

    f(5, foo);
    f(std::string("thing"), bar);

    return 0;
}

【讨论】:

  • 这又是函数指针。对?我试过这个。多次调用时性能不佳。
  • 性能?它们更像是一种用于保存代码的工具,而不是真正用于提高性能的工具。
  • 这正是我所关心的。具有不会降低性能的实现。无论如何,谢谢你的代码!
  • 我将把它留在这里:en.wikipedia.org/wiki/Policy-based_design
  • 顺便说一句......通常更多的代码数量意味着更好的性能(这就是编译器展开循环的原因)......但这也意味着更难阅读代码。注意性能改进。
【解决方案2】:

好的,现在说的事实来了:成员指针也是指针(好的,有时它们只是偏移量,在多重/虚拟继承的情况下它可以更加复杂......)。现在也许是一个可能的解决方案,尽管我不知道您将成员函数指针传递给模板的模板方法的实际用例是什么......

template <typename T>
class C
{
public:
    C()
    {
        f(5, &C::f);
    }

    template <typename Func>
    int f(int a, Func somefunc)
    {
        (this->*somefunc)(a);
        return 0;
    }
    void f(int i)
    {
        printf("%s(%d)\n", __FUNCTION__, i);
    }
    void g(int i)
    {
        printf("%s(%d)\n", __FUNCTION__, i);
    }
};

int main()
{
    C<int> c;
    c.f(6, &C<int>::g);
    return 0;
}

【讨论】:

  • 其实我想让 f 成为一个 API。所以它不知道类或其成员函数的实现。
  • @TOWI_Parallelism 在这种情况下,您还必须将实例指针连同成员指针一起传递给 f(),因为没有实例指针,成员指针将毫无用处。实例指针 + 方法指针一起基本上是一个委托(委托 == 指向实际实例的方法的指针),不幸的是 C++ 不支持它,但是在 C++11 中,您有多种选择来实现您的目标,具体取决于您实际想要的去做。
  • @TOWI_Parallelism 我之前关于委托的说法并不完全正确,委托不一定是实例指针+方法。委托只是一个可调用对象,它就像一个函数,但它的实际实现实际上可以由普通函数或可选的具有绑定实例指针/ this 指针参数的方法支持。
  • 你确定在 C++ 中不可能吗?
  • @TOWI_Parallelism C++ 本身并不支持委托,但您可以使用 C++11 功能很好地模拟它们。问题是:你想达到什么目标?也许你需要的只是 lambda/std::function,也许是一些可变参数模板魔法。目标是提供一个易于使用的 API,当有人在您的 API 之上编写代码时,该 API 会生成漂亮的代码。