c ++错误C2064用于C ++模板中的嵌套绑定

时间:2016-06-27 15:00:09

标签: c++ bind

如果我编译下面的代码,我得到一个: microsoft visual studio 12.0 \ _vc \ include \ xrefwrap(58):错误C2064:术语不评估为带有2个参数的函数

在对累积算法的调用中,如果我将代码更改为function<double(double, Position const&) > f = bind(sum, placeholders::_1, bind(mem_fn(&Position::getBalance), placeholders::_2));double sum = accumulate(balances.begin(), balances.end(), 0., f);,则一切编译都很好。我也尝试使用非成员函数,但它既不起作用。

class Position
{
private:
    double m_balance;
public:
    Position(double balance) :
        m_balance(balance)
    {}

    double getBalance() const
    {
        return m_balance;
    }
};

static double sum(double v1, double v2)
{
    return v1 + v2;
}

int main(int argc, char ** argv)
{
    std::vector< Position > balances;
    for (size_t i = 0; i < 10; i++)
    {
        balances.push_back(Position(i));
    }

    double sum = accumulate(balances.begin(), balances.end(), 0., bind(sum, placeholders::_1, bind(mem_fn(&Position::getBalance), placeholders::_2)));
    cout << sum << endl;
    return 0;
}

1 个答案:

答案 0 :(得分:4)

这将解决它:

double sum = accumulate(balances.cbegin(), 
                        balances.cend(), 
                        0.0 , 
                        std::bind(std::plus<>(), 
                                  placeholders::_1,
                                  std::bind(&Position::getBalance, placeholders::_2)));

或者我们可以对我们的程序员们友善:

auto add_balance = [](auto x, auto& position) {
  return x + position.getBalance();
};

double sum = accumulate(balances.cbegin(), 
                        balances.cend(), 
                        0.0 , 
                        add_balance);

当然我们可以内联lambda。没有性能差异。哪一个看起来更清楚将是个人偏好的问题。

double sum = accumulate(balances.cbegin(), 
                        balances.cend(), 
                        0.0 , 
                        [](auto x, auto& position) 
                        {
                          return x + position.getBalance();
                        });

或者我们可以编写一个复杂的函子来完成类似的工作。这是前lambda方式:

template<class Op>
struct PositionOp
{
  using mfp_type = double (Position::*)() const;

  PositionOp(Op op, mfp_type mfp) : op(op), mfp(mfp) {}

  template<class T>
  auto operator()(T x, const Position& pos) const {
    return op(x, (pos.*mfp)());
  }

  Op op;
  mfp_type mfp;
};

template<class Op>
auto position_op(Op op, double (Position::*mfp)() const)
{
  return PositionOp<Op>(op, mfp);
}

...

double sum = accumulate(balances.cbegin(), 
                        balances.cend(), 
                        0.0 , 
                        position_op(std::plus<>(), &Position::getBalance)); 

...但我希望你们同意这是可怕的。