【问题标题】:Confusion regarding std::transform - converting std::map's value_type::second to a std::vector关于 std::transform 的困惑 - 将 std::map 的 value_type::second 转换为 std::vector
【发布时间】:2012-03-21 02:00:43
【问题描述】:

您好,谁能告诉我为什么 VS2010 给我这个代码的错误,我看不出它有什么问题?

错误代码:错误 C2679:二进制“=”:未找到采用“std::vector<_ty>”类型右侧操作数的运算符(或没有可接受的转换)

// Elements container
typedef std::vector<CFVFElementPtr> ElementArray;
typedef std::map<CVertexSemantic::Type, ElementArray> ElementsMap;

// Create an empty array of elements
ElementsMap::value_type::second_type allElements;

// Concatinate each std::vector found within the map
std::transform(m_elementsMap.begin(), m_elementsMap.end(),
std::insert_iterator<ElementArray>(allElements, allElements.end()),
select2nd<ElementsMap::value_type>() );

我想做的就是这个

for (auto i = m_elementsMap.begin(); i != m_elementsMap.end(); ++i)
{
    const ElementArray& elements = (*i).second;
    allElements.insert(allElements.end(), elements.begin(), elements.end());
}

作为对 Pablo 的回应,我尝试创建一个接受 ElementArray 数组的自定义迭代器,但我现在遇到了一大堆错误。

template < class Container >
class container_insert_interator
{
public:
    typedef container_insert_interator<Container> this_type;
    typedef Container container_type;
    typedef typename Container::const_reference const_reference;
    typedef typename Container::value_type valty;

    explicit container_insert_interator (Container& cont, typename   Container::iterator iter) 
            : container(&cont), iter(iter)
    { }

    this_type& operator = (typename const_reference value)
    { 
        iter = container->insert( iter, std::begin(value), std::end(value) );
        ++iter;
        return *this;
    }

    this_type& operator* ()
    { 
       return *this;
    }

    this_type& operator++ ()
    { 
           return *this;
    }

    this_type operator++ (int)
    {
       return *this;
    }

protected:
    Container* container; // pointer to container
    typename Container::iterator iter ; // iterator into container
};

【问题讨论】:

  • 如果有人想知道select2nd 是什么,它只会返回 std::map 的 value_type 的 std::pair.second。

标签: c++ stl


【解决方案1】:

问题是ElementsMap::value_type::second_typeElementArray。也就是说,您正在尝试将ElementArray 的实例插入到ElementArray 中,该ElementArray 确实包含CFVFElementPtr 的实例。

更新:将 operator= 的声明从

this_type& operator = (typename const_reference value)

template<typename OtherContainer>
this_type& operator = ( OtherContainer const& value)

几乎可以工作。除了 VS 2010 或 GCC 4.6.1 都没有提供返回迭代器的 vector::insert 重载。如果您希望您的范围插入返回一个迭代器来替换 iter,您可能需要更新的编译器。

将实现更改为始终插入末尾,即

container->insert( container->end(), std::begin(value), std::end(value) );

operator= 中的 GCC 4.6.1 编译良好(当然,您可以删除迭代器类中对 iter 的所有引用)。

【讨论】:

  • 我尝试创建自己的接受ElementArray 的迭代器,但它仍然不起作用。
  • 使用template&lt;typename OtherContainer&gt; this_type&amp; operator = (OtherContainer const&amp; value) 比我在下面发布的版本更通用,因为它允许任何 STL 容器类型,所以我会接受你的回答。
【解决方案2】:

您可以考虑使用可以将元素附加到目标数组的仿函数以及std::for_each 来遍历地图:

struct ElementArray_appender
{
    ElementArray_appender( ElementArray& dest_) : dest(dest_) {
    };

    void operator()( ElementsMap::value_type const& map_item) {
        ElementArray const& vec( map_item.second);

        dest.insert( dest.end(), vec.begin(), vec.end());
    };

private:
    ElementArray& dest;
};



// in whatever function:

std::for_each( m_elementsMap.begin(), m_elementsMap.end(), ElementArray_appender(allElements));

【讨论】:

    【解决方案3】:

    我找到了答案,问题出在我的自定义迭代器上。正确的工作是

    template < class Container >
    class container_back_insert_interator
    {
    public:
        typedef container_back_insert_interator<Container> this_type;
        typedef Container container_type;
        typedef typename container_type::const_reference const_reference;
        typedef typename container_type::value_type valty;
    
        explicit container_back_insert_interator (container_type& cont) 
        : container(&cont)
        { }
    
        this_type& operator = (const_reference value)
        { 
            container->insert( container->end(), std::begin(value), std::end(value) );
            return *this;
        }
    
        this_type& operator* ()
        { 
            return *this;
        }
    
        this_type& operator++ ()
        { 
            return *this;
        }
    
        this_type operator++ (int)
        {
            return *this;
        }
    
    protected:
        container_type* container; // pointer to container
    };
    
    template < class Container >
    inline container_back_insert_interator<Container> container_back_inserter(Container& cont)
    {
        return container_back_insert_interator<Container>(cont);
    }
    

    但是,我必须警告说,如果您确实在 Visual Studio 2010 中使用它,您将必须实现 std::transform 的 SGI 形式。 VS2010 附带的版本由于某种原因引发了许多错误,所有这些错误都位于 &lt;xutility&gt; 标头中。

    这个std::transform 工作正常。

    【讨论】:

      猜你喜欢
      • 2020-07-03
      • 1970-01-01
      • 1970-01-01
      • 2018-04-07
      • 2016-02-04
      • 2019-10-20
      • 1970-01-01
      • 2016-03-31
      • 2020-12-09
      相关资源
      最近更新 更多