Search code examples
c++booststdplaceholder

Conversion of boost placeholders with arithmetic to std


I am working on converting a C++ project which used boost and placeholders to transform a map the existing logic was:

inline const std::vector<uint32_t> average(const std::pair<uint16_t, std::vector<uint32_t> >& left,
                                           const std::pair<uint16_t, std::vector<uint32_t> >& right)
{
    // Ejector rates should be symmetrical
    assert(left.second.size() == right.second.size());
    std::vector<uint32_t> result;
    result.reserve(left.second.size());
    namespace bl = boost::lambda;
    // Walk both, do funny thing with each element in turn. Stuff into result.
    std::transform(left.second.begin(), left.second.end(), right.second.begin(), std::back_inserter(result), (bl::_1 + bl::_2) / 2);
    return result;
}

I want to replace the boost references with std:

inline const std::vector<uint32_t> average(const std::pair<uint16_t, std::vector<uint32_t> >& left,
                                           const std::pair<uint16_t, std::vector<uint32_t> >& right)
{
    // Ejector rates should be symmetrical
    assert(left.second.size() == right.second.size());
    std::vector<uint32_t> result;
    result.reserve(left.second.size());
    namespace bl = boost::lambda;
    // Walk both, do funny thing with each element in turn. Stuff into result.
    std::transform(left.second.begin(), left.second.end(), right.second.begin(), std::back_inserter(result),
        (std::placeholders::_1 + std::placeholders::_2) / 2);
    return result;
}

I'm getting:

error C2784: 'std::_Deque_const_iterator<_Mydeque> std::operator +(_Deque_const_iterator<_Mydeque>::difference_type,std::_Deque_const_iterator<_Mydeque>)' : could not deduce template argument for 'std::_Deque_const_iterator<_Mydeque>' from 'std::_Ph<2>'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\deque(555) : see declaration of 'std::operator +'

On the line which contains:

(std::placeholders::_1 + std::placeholders::_2) / 2);

What is the correct way to do this?


Solution

  • Just use a lambda. In general case you can use const auto refs to avoid coping of parameters:

    std::transform(left.second.begin(), left.second.end(), right.second.begin(), std::back_inserter(result), [] (auto const &a, auto const &b) { return (a+b)/2; });
    

    In case of small numeric types like int you can pass them by value and use just const auto or specify the type explicitly:

    std::transform(left.second.begin(), left.second.end(), right.second.begin(), std::back_inserter(result), [] (uint32_t a, uint32_t b) { return (a+b)/2; });