【问题标题】:Bind pointer to member operators in C++将指针绑定到 C++ 中的成员运算符
【发布时间】:2009-04-14 06:57:54
【问题描述】:

它们的意义何在?
我从来没有将它们用于任何事情,而且我根本看不到自己需要使用它们。
我错过了他们的一些东西还是他们几乎没用?

编辑:我对它们了解不多,因此可能需要对它们进行描述...

【问题讨论】:

  • 不,更具体地说,是 .* 和 ->* 运算符。
  • 我怀疑不是,我认为他在谈论指向成员运算符(例如,operator+)的指针
  • @nevets:这与我正在寻找的内容有关,但该问题没有更基本的信息,我需要将其与我的问题联系起来。
  • 我还更新了我的回答来描述什么 PMF 是。希望这能让您更轻松地与普通的 jane 函数指针进行比较。 :-)

标签: c++ operators


【解决方案1】:

PMF(指向成员函数的指针)类似于普通(静态)函数指针,除了因为非静态成员函数需要指定 this 对象,PMF 调用语法(.* 或 @987654325 @) 允许指定 this 对象(在左侧)。

这是一个正在使用的 PMF 示例(注意“魔术”行,其中使用了 .* 运算符:(lhs.*opit->second)(...),以及创建 PMF 的语法 &class::func):

#include <complex>
#include <iostream>
#include <map>
#include <stack>
#include <stdexcept>
#include <string>

namespace {
    using std::cin; using std::complex; using std::cout;
    using std::invalid_argument; using std::map; using std::stack;
    using std::string; using std::underflow_error;

    typedef complex<double> complexd;
    typedef complexd& (complexd::*complexd_pmf)(complexd const&);
    typedef map<char, complexd_pmf> opmap;

    template <typename T>
    typename T::reference top(T& st) {
        if (st.empty())
            throw underflow_error("Empty stack");
        return st.top();
    }
}

int
main()
{
    opmap const ops{{'+', &complexd::operator+=},
                    {'-', &complexd::operator-=},
                    {'*', &complexd::operator*=},
                    {'/', &complexd::operator/=}};

    char op;
    complexd val;
    stack<complexd> st;

    while (cin >> op) {
        opmap::const_iterator opit(ops.find(op));
        if (opit != ops.end()) {
            complexd rhs(top(st));
            st.pop();
                                        // For example of ->* syntax:
            complexd& lhs(top(st));     // complexd* lhs(&top(st));
            (lhs.*opit->second)(rhs);   // (lhs->*opit->second)(rhs);
            cout << lhs << '\n';        // cout << *lhs << '\n';
        } else if (cin.unget() && cin >> val) {
            st.push(val);
        } else {
            throw invalid_argument(string("Unknown operator ") += op);
        }
    }
}

[Download]

这是一个简单的 RPN 计算器,使用复数而不是实数(主要是因为 std::complex 是具有重载运算符的类类型)。我已经用clang 进行了测试;您的里程可能会因其他平台而异。

输入的格式应为(0,1)。空格是可选的,但可以添加以提高可读性。

【讨论】:

  • 代码有 no 错误检查,但我希望你能明白。 :-D
  • 是的,这是有道理的。谢谢你的例子。
  • 更新了我的版本以实际添加一些错误检查,因为在空堆栈上获取段错误真的让我很烦恼。 :-)
【解决方案2】:

绑定一个指向函数的指针在各种情况下都非常有用。基本上,它允许您将函数称为变量,这使您可以在运行时选择要调用的函数。

其中一个用途是在“回调”中。假设我想让一些后台进程工作一段时间,并让我们知道它什么时候完成(这样我们就可以更新 GUI 或其他东西)。但有时,我们可能希望这个后台进程调用一个方法,有时,我们希望它调用不同的方法。与其编写此后台进程的两个版本,不如编写它,以便后台进程接收指向我们希望它“回调”的函数的指针。然后,当该过程完成时,它首先调用它给出的任何函数。

基本上,它只是让您在决定调用哪个方法时拥有更大的灵活性。这样,它与多态非常相似。事实上,在幕后,我相信 C++ 使用指向函数的指针来促进多态性(通过为每个类存储指向函数的不同指针表)

【讨论】:

    【解决方案3】:

    如果我正确理解您的问题。为什么不呢?

    struct test
    {
        test* operator->() 
        { 
            std::cout << "test::operator->";
            return this; 
        }
    };
    
    test tt;
    boost::bind( &test::operator ->, _1 )( tt );
    

    【讨论】:

    • 我的问题更多是关于这些运算符是什么,而不是使用运算符的替代方法。
    猜你喜欢
    • 2023-03-24
    • 2012-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-24
    • 1970-01-01
    • 2011-05-09
    • 2013-05-02
    相关资源
    最近更新 更多