c++ - 如何使用 std::partial_sum 并输出到 std::map?

标签 c++ c++11 stdmap

我想要一个只有 { {0,1},{1,2},{2,3},{3,4},{4,5} }, c++11 的输出映射。有任何想法吗?

std::map<int, int> m, out;
for( auto i=0; i < 5; ++i ) 
    m[i] = 1;

std::partial_sum( m.begin(), m.end(), std::inserter( out, out.begin() ),
        []( const std::pair<int,int>& a, const std::pair<int,int>& b ) 
             { return std::pair<int,int>( a.first, a.second + b.second ); } 
);
这给出了编译错误:
/usr/include/c++/5/bits/stl_pair.h: In instantiation of ‘std::pair<_T1, _T2>& std::pair<_T1, _T2>::operator=(std::pair<_U1, _U2>&&) [with _U1 = int; _U2 = int; _T1 = const int; _T2 = int]’:
/usr/include/c++/5/bits/stl_numeric.h:295:12:   required from ‘_OutputIterator std::partial_sum(_InputIterator, _InputIterator, _OutputIterator, _BinaryOperation) [with _InputIterator = std::_Rb_tree_iterator<std::pair<const int, int> >; _OutputIterator = std::insert_iterator<std::map<int, int> >; _BinaryOperation = main()::<lambda(const std::pair<int, int>&, const std::pair<int, int>&)>]’
../src/test_cumsum.cpp:43:130:   required from here
/usr/include/c++/5/bits/stl_pair.h:188:10: error: assignment of read-only member ‘std::pair<const int, int>::first’
first = std::forward<_U1>(__p.first);

最佳答案

你不能。至少不是直接的。问题是std::map<int, int>::iterator::value_typestd::pair<const int, int> ,以及 const防止分配给该类型的对象。
——
看看这个possible implementationstd::partial_sum :

template<class InputIt, class OutputIt, class BinaryOperation>
constexpr // since C++20
OutputIt partial_sum(InputIt first, InputIt last, 
                     OutputIt d_first, BinaryOperation op)
{
    if (first == last) return d_first;
 
    typename std::iterator_traits<InputIt>::value_type sum = *first;
    *d_first = sum;
 
    while (++first != last) {
       sum = op(std::move(sum), *first); // std::move since C++20
       *++d_first = sum;
    }
    return ++d_first;
}
请注意 sum通过分配 op 的结果在每次迭代中得到修改.因为 sum.firstconst那是不可能的;因此编译错误。
——
你可以做的是定义一个迭代器类型来包装 std::map::iterator并去掉 const .例如,以下将起作用:
template <typename Pair>
struct RemoveFirstConstHelper
{
    using type = Pair;
};

template <typename T1, typename T2>
struct RemoveFirstConstHelper<std::pair<const T1, T2>>
{
    using type = std::pair<T1, T2>;
};

template <typename MapIterator>
class RemoveFirstConstIter
{
public:
    using difference_type = std::ptrdiff_t;
    using value_type = typename RemoveFirstConstHelper<typename MapIterator::value_type>::type;
    using pointer = value_type*;
    using reference = value_type;
    using iterator_category = std::input_iterator_tag;
    
    RemoveFirstConstIter(MapIterator it) : it_{it} {}
    
    reference operator*()
    {
        return *it_;
    }
    
    RemoveFirstConstIter& operator++()
    {
        ++it_;
        return *this;
    }
    
    RemoveFirstConstIter operator++(int) const
    {
        RemoveFirstConstIter temp{*this};
        ++temp;
        return temp;
    }
    
    bool operator==(const RemoveFirstConstIter& other) const
    {
        return it_ == other.it_;
    }
    
    bool operator!=(const RemoveFirstConstIter& other) const
    {
        return !(*this == other);
    }
    
private:
    MapIterator it_;
};
Live Demo
或者你可以自己写 partial_sum map 的实现。这对我来说似乎更简单。

关于c++ - 如何使用 std::partial_sum 并输出到 std::map?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65913287/

相关文章:

c++ - 我应该使用 virtual、override 还是同时使用这两个关键字?

在 Mac OS X Snow Leopard 上使用 Xcode 的 C++11

c++ - 我可以扩展 std::map::lower_bound 以搜索非 key_type 参数吗?

c++ - 如何使用以用户定义类型为键的std::maps?

c++ - 是否有需要多个所有者的智能指针类型?

c++ - 具有类作为键的映射,允许重复键

c++ - C++ 中的一行用户输入赋值

c++ - 如何在各个参数中拆分#__VA_ARGS__

c++ - 如何使用 std::vector<std::mutex> 之类的东西?

c++ - 增加无序映射中默认构造的 int