【问题标题】:some practical uses of mem_fn & bindmem_fn & bind 的一些实际用途
【发布时间】:2012-04-26 18:45:39
【问题描述】:

有人可以推荐 tr1 的 mem_fn 和绑定实用程序的一些很酷的实际用途吗?我不需要深奥的 C++ 来开发库。只是一些利用这些的应用程序级编码。

任何帮助将不胜感激。

【问题讨论】:

    标签: c++ stdbind tr1 mem-fun


    【解决方案1】:

    我已将std::mem_fnstd::bind 用于反射样式属性。

    所以我会有一个带有AbstractProperty 向量的class SomeClassAbstractProperty可以有几种不同类型的类,比如PropertyFloatPropertyU32等。

    然后在SomeClass 中,我会将bind 发送到std::function 以获取AbstractProperty。我会 bind 这样做

    std::bind(std::mem_fn(&SomeClass::SomeFloatGetter), this)
    

    对于 setter 类型的函数,我会使用

     std::bind(std::mem_fn(&SomeClass::SomeSetterGetter), this, std::placeholders::_1)
    

    当然,为类设置函数比较困难,但我确实使用std::function 来做到这一点。在PropertyFloat我有

    typedef std::function<float(void)> GetterType;
    

    所以它通过一个函数设置它,我将传递第一个 std::bind 作为参数显示

    typename PropertyFloat::GetterType getter
    

    当然,这些类型可以使用模板并更通用,但这取决于您的开发目标。

    【讨论】:

    • +1。这也是我想尝试的事情。你有更多关于反射位的细节要分享吗?
    • 嗯,这基本上是我能描述的最多的了,而不必将整个代码库放在 github 或其他东西上(并且代码是封闭源代码)。不过,我更新了我的帖子以提供更多详细信息。不幸的是,我在这里开发的系统类型的文档并不多。我正在编写关于整个系统的大型文档,但还没有完成。我可以说我已经使用std::mem_fnstd::bind 进行这种事情将近两年了,虽然没有任何问题。
    • 也不是,这是我所知道的mem_fnbind 最复杂的用法之一。如果你想练习使用这两种类型,也许你应该看看它们的一些小用法(我在开发这个系统之前就做过)。这个反射系统是围绕这两种类型(和std::function)的使用而构建的。虽然老实说,这可能只是用成员函数指针替换(理论上)。它们各有优缺点。
    【解决方案2】:

    通常,将成员函数用于回调可能会很麻烦,例如在&lt;algorithm&gt; 函数中使用。 std::mem_fn(现在已经标准化,因此您不再需要使用 tr1 命名空间)创建一个可调用对象,该对象可用作这些函数的函子对象。有关其使用示例,请参阅使用 std::string::sizethis link 的示例部分。

    std::bind 可以用于例如您在编译时不知道实际参数,但必须创建一个带有参数运行时的可调用对象。它也可以用于重新排序参数,例如:

    auto f1 = std::bind(printf, _2, _1);
    f1(42, "%d\n");
    

    (好吧,愚蠢的例子,但我现在能想到的。)

    【讨论】:

      【解决方案3】:

      以下代码计算大于五的元素个数:

      #include <functional>
      #include <algorithm>
      #include <vector>
      #include <iostream>
      
      int main() {
        using namespace std;
        vector<int> v { 1, 5, 2, 7, 6, 7, 5 };
        cout << count_if(v.begin(), v.end(),
                         bind(greater<int>(), placeholders::_1, 5)) << endl;
      }
      

      【讨论】:

      • 在这个例子中,为什么 bind 比 lambda 函数更好?
      【解决方案4】:

      一个问题是 lambda 很难使用前向声明的类中的方法。我使用 bind 来使用使用前向声明类中的方法的成员函数。我找不到使用 lambda 的解决方案。场景如下:我有一个在类 A 中定义的成员函数 f1、f2、... 的列表,其中一些使用了前向声明类中的方法。我希望能够使用这些 fi 函数中的任何一个灵活地交换表达式树 B 类节点的运算符。在 B 中,定义了一个通用运算符。我使用 bind 将 fi 函数自适应地关联到通用运算符。这样,fi 成员函数定义可以在放置前向声明的 A.h 文件中进行原型化,然后可以将 fi 函数的实现放在 A.cpp 文件中并由 B 类访问。我很好奇其他人是否遇到过这个问题以及他们是如何处理的。

      【讨论】:

        猜你喜欢
        • 2011-06-16
        • 1970-01-01
        • 2014-06-19
        • 2010-10-17
        • 2020-10-06
        • 2011-07-09
        • 2021-06-29
        • 2010-10-17
        相关资源
        最近更新 更多