当调用std::transform时,UnaryOperator可以是成员函数吗?

3

基于std::transform

的内容:

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

op 可以作为成员函数吗?如果可以,如何调用它?


请查看Boost.Bind - ildjarn
http://stackoverflow.com/questions/1762781/mem-fun-and-bind1st-problem - q0987
你的问题有点含糊不清。你希望将 op 成为哪个类的成员?是 *first1 的类,*result 的类,*this 的类还是其他类? - Robᵩ
@Rob,最好我两种情况都知道。 - q0987
@q0987 - 请看我的回答。它描述了op*first1类的成员和op*this的成员的情况。你应该能够从中推广出来。 - Robᵩ
3个回答

4
不行(嗯,不能直接这样做)。您需要使用适配器,可以使用旧的std::mem_fun(与bind1st一起使用,如果我没记错的话),或者使用std::bind/boost::bind
std::transform(
    xs.begin(), xs.end(), ys.begin(),
    std::bind(&Class::member, &class_instance)
);

1
class_instance 不是应该由 std::transform 提供吗?所以仅使用 std::mem_fun 本身可能比 bind1st 更合适。 - Ben Voigt
&class_instance替换为std::placeholders::_1 - Xeo
@Ben:mem_fn是适用于Boost/C++11的版本。 - Xeo
@BenVoigt:不知道,OP可能是关于任何一个的。 - Cat Plus Plus
1
如果我没记错,C++11已经弃用了std::mem_fun() - wilhelmtell
我真的非常羡慕在StackOverflow上的你们所有人,都能在项目中使用新的C++11高级特性,你们都是学生还是业余爱好者?如果你们能在白天的工作中使用这些东西,请告诉我你们在哪里工作。;-) - Frerich Raabe

3

如果您将调用包装在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(); });
  }
};

2

你需要一个帮助对象,像 std::less 一样,但是针对的是一元运算符。

C++11 lambdas 让这变得十分容易:

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的例子,它们有什么问题吗? - Ben Voigt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接