【问题标题】:is there a use for &func or class::func in c++?在 C++ 中有 &func 或 class::func 的用途吗?
【发布时间】:2010-10-11 10:59:43
【问题描述】:

这似乎不一致。为什么我们使用 &Example::func 而不是 Example::func? Example::func 或 &exampleFunction 有没有用处?似乎我们不能引用一个函数,以便排除 Example::func。我想不出一种使用 &exampleFunction 的方法,因为 exampleFunction 已经返回了一个指针。

#include <iostream>
class Example {
public:
    void func() { std::cout <<"print me\n"; }
};
void exampleFunction() { std::cout << "print me too\n"; }
typedef void (Example::*ExampleFunc_t)(); 
typedef void (*ExampleFunction_t)();
int main()
{
    Example e;
    ExampleFunc_t     f  = &Example::func;
    ExampleFunction_t f2 = exampleFunction;
    (e.*f)();
    f2();
    return 0;
} 

【问题讨论】:

    标签: c++ function-pointers member-pointers


    【解决方案1】:

    因为这是标准定义函数指针的方式。

    您实际上总是必须使用地址运算符&amp; 来获取指向函数的指针,但是对于常规函数和静态成员函数,标准中定义了从函数到指针到函数的隐式转换。

    这不是为(非静态)成员函数定义的,因为您无法获得非静态成员函数的左值。

    来自 C++ 标准:

    4.3 函数到指针的转换

    1. 函数类型 T 的左值可以转换为类型的右值 “指向 T 的指针。”结果是一个指向函数的指针。

    脚注 52:

    这种转换永远不会应用于非静态成员函数,因为 无法获取引用非静态成员函数的左值。

    出于一致性原因,我认为他们宁愿只允许 &function,但隐式转换只是 C 遗产的产物...

    【讨论】:

    • 在 C++ 中也有函数引用(typedef void (&FuncRef_t)()),但没有成员函数引用。
    • 是的,我认为对函数进行隐式转换很有用。因为大多数情况下你还是想传递一个指针(你不能“传递一个函数”,所以它通过隐式转换传递一个指向它的指针)。我想 T::f 不够的原因是因为它会模棱两可:如果它会是
    • 已经有成员函数指针,不能写Base::f();调用基类函数。你需要写 (this->*Base::f)();这有点糟糕。因此,我认为让 &T::foo 获取指针是一个很好的解决方案。
    【解决方案2】:

    重点是使用Function Pointers。举一个非常粗略的例子,假设你有一个有几个成员变量的类,你可能需要通过这些成员变量对该类类型的数组的元素进行排序,如下所示:

    struct CL {
        int x, y, z;
    };
    
    bool sort_by_x(const CL& obj1, const CL& obj2);
    bool sort_by_y(const CL& obj1, const CL& obj2);
    bool sort_by_z(const CL& obj1, const CL& obj2);
    
    ...
    
    CL obj[100];
    ...
    sort(obj, obj+100, sort_by_x);
    ...
    sort(obj, obj+100, sort_by_y);
    ...
    sort(obj, obj+100, sort_by_z);
    

    这里 std::sort 用于对 CL 对象数组进行排序。看第三个参数,它是一个函数的名字。 std::sort 函数可以在第三个参数中获取函数指针,并将该函数用作比较器来对数组进行排序。如何定义 sort_by_* 函数以使 std::sort 按预期工作取决于我们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-20
      • 1970-01-01
      • 2021-04-14
      • 2010-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-10
      相关资源
      最近更新 更多