【问题标题】:Can UnaryOperator be a member function when std::transform is called调用 std::transform 时 UnaryOperator 可以是成员函数吗
【发布时间】:2012-01-26 19:53:48
【问题描述】:

基于std::transform

template < class InputIterator, class OutputIterator, class UnaryOperator >
  OutputIterator transform ( InputIterator first1, InputIterator last1,
                             OutputIterator result, UnaryOperator op );

op 可以成为成员函数吗?如果是这样,我该如何称呼它?

【问题讨论】:

  • Boost.Bind
  • 你的问题有点模棱两可。您希望op 成为哪个班级的成员? *first1 的类,*result 的类,*this 的类,还是其他一些类?
  • @Rob,我最好知道这两种情况。
  • @q0987 - 看我的回答。它描述了op*first1 类成员和op*this 成员的情况。您应该能够从那里进行概括。

标签: c++ stl


【解决方案1】:

不(嗯,不直接)。您需要使用适配器,旧的std::mem_fun(连同bind1st,IIRC)或std::bind/boost::bind

std::transform(
    xs.begin(), xs.end(), ys.begin(),
    std::bind(&Class::member, &class_instance)
);

【讨论】:

  • class_instance 不应该由std::transform 提供吗?所以std::mem_fun 本身可能比bind1st 更合适。
  • &amp;class_instance 替换为std::placeholders::_1
  • @Ben:mem_fn 是合适的 Boost/C++11 版本。
  • @BenVoigt:不知道,OP 也可以,真的。
  • IIRC C++11 已弃用 std::mem_fun().
【解决方案2】:

如果你将调用封装在 lambda 中,这很容易做到:

#include <algorithm>
#include <vector>

class C {
public:
  int op() const { return 1; }
};

class D {
  int op() { return 1; }
  void f() {
    std::vector<C> xs;
    std::vector<int> ys;
    std::transform(xs.begin(), xs.end(), ys.begin(),
      [](const C& x) { return x.op(); });
    std::transform(xs.begin(), xs.end(), ys.begin(),
      [this](const C& x) { return this->op(); });
  }
};

【讨论】:

    【解决方案3】:

    您需要一个辅助对象,例如 std::less,但需要一个一元运算符。

    C++11 lambda 让这变得异常简单:

    std::transform(xs.begin(), xs.end(), ys.begin(), [](the_type x){ return -x; });
    std::transform(xs.begin(), xs.end(), ys.begin(), [](the_type x){ return !x; });
    std::transform(xs.begin(), xs.end(), ys.begin(), [](the_type x){ return ~x; });
    

    或者,使用这些灵活的助手:

    struct negate
    {
        template<typename T>
        auto operator()(const T& x) const -> decltype(-x) { return -x; }
    };
    
    struct invert
    {
        template<typename T>
        auto operator()(const T& x) const -> decltype(!x) { return !x; }
    };
    
    struct complement
    {
        template<typename T>
        auto operator()(const T& x) const -> decltype(~x) { return ~x; }
    };
    
    std::transform(xs.begin(), xs.end(), ys.begin(), negate());
    std::transform(xs.begin(), xs.end(), ys.begin(), invert());
    std::transform(xs.begin(), xs.end(), ys.begin(), complement());
    

    【讨论】:

    • @q0987:我展示了 lambda 的示例。他们有什么问题吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-23
    • 1970-01-01
    • 2015-01-15
    • 1970-01-01
    • 2013-02-01
    • 2020-12-10
    • 1970-01-01
    相关资源
    最近更新 更多