Может ли UnaryOperator быть функцией-членом при вызове std :: transform - PullRequest
2 голосов
/ 26 января 2012

На основе std :: transform

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

Может ли op быть функцией-членом?Если да, то как мне это назвать?

Ответы [ 3 ]

3 голосов
/ 27 января 2012

Это довольно легко сделать, если вы заключите вызов в лямбду:

#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 голосов
/ 26 января 2012

Нет (ну не напрямую). Вам необходимо использовать адаптер, либо старый std::mem_fun (вместе с bind1st, IIRC), либо std::bind / boost::bind.

std::transform(
    xs.begin(), xs.end(), ys.begin(),
    std::bind(&Class::member, &class_instance)
);
1 голос
/ 27 января 2012

Вам нужен вспомогательный объект, например std::less, но для унарного оператора.

C ++ 11 лямбд делают это невероятно простым:

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());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...