Home Articles

Iterator对矢量对,并使用std :: copy打印结果

Asked
Viewed 1227 times
0

我有以下向量:

std::vector<std::pair<int,std::string>> songs;

我想使用std :: copy将向量中的元素(比如说int)传递给ostream,类似于以下哪些方法不起作用:

std::copy(songs.begin(),songs.end(),std::ostream_iterator<int>(std::cout,""));

我知道我可以这样做:

for(auto it=songs.begin(); it!=songs.end(); ++it)
    {
      std::cout << (*it).first;
    }

但我想知道是否有可能在C中创建一个迭代器,它只指向该对中的一个元素,然后使用它来迭代并将元素复制到ostream,或者如何让std :: copy在上面工作?

1 Answer

  • 5

    正如克里斯mentioned在评论中,最简单的解决方案是使用 std::transform

    std::transform( songs.begin(), songs.end(), 
                    std::ostream_iterator<int>( std::cout, "\n" ),
                    []( decltype(v)::value_type const& p ) -> decltype(p.first) {
                        return p.first;
                    }
                  );
    

    如果要转到自定义迭代器路径,请创建一个模仿 ostream_iterator 行为的类型,另外使用 std::get 仅检索您关注的项目 .

    template<std::size_t N>
    struct get_tuple_item_iterator
    : public std::iterator<std::output_iterator_tag, void, void, void, void>
    {   
        get_tuple_item_iterator( std::ostream& os, std::string term )
        : os_(os)
        , term_(std::move(term))
        {}
    
        template<typename... T>
        get_tuple_item_iterator& operator=( std::tuple<T...> const& elem )
        {
            static_assert(N < sizeof...(T), "N is out of range");
            os_ << std::get<N>( elem ) << term_;
            return *this;
        }
    
        template<typename T1, typename T2>
        get_tuple_item_iterator& operator=( std::pair<T1, T2> const& elem )
        {
            static_assert((N == 0) || (N == 1), "N must be 0 or 1 for std::pair");
            return operator=( std::tie( elem.first, elem.second ) );
        }
    
        get_tuple_item_iterator& operator*() { return *this; }
        get_tuple_item_iterator& operator++() { return *this; }
        get_tuple_item_iterator& operator++( int ) { return *this; }
    
    private:
        std::ostream& os_;
        std::string term_;
    };
    

    用它作为

    std::copy( songs.begin(), songs.end(), 
               get_tuple_item_iterator<0>( std::cout, "\n" ) );
    

Related