关于std :: transform的困惑 - 将std :: map的value_type :: second转换为std :: vector

时间:2012-03-21 02:00:43

标签: c++ stl

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

错误代码:错误C2679:binary'=':找不到运算符,该运算符采用'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
};

3 个答案:

答案 0 :(得分:1)

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

更新:更改this_type& operator = (typename const_reference value) 的声明

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

vector::insert

几乎有效。除了VS 2010或GCC 4.6.1都没有提供返回迭代器的iter重载。如果希望远程插入返回迭代器以替换container->insert( container->end(), std::begin(value), std::end(value) ); ,则可能需要更新的编译器。

将实现更改为始终在最后插入,即

operator=
iter中的

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

答案 1 :(得分:1)

您可以考虑使用一个可以将元素附加到目标数组的仿函数以及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));

答案 2 :(得分:0)

我找到了答案,这个问题与我的自定义迭代器有关。正确的工作是

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中使用它,则必须实现SGI形式的std :: transform。 VS2010附带的版本由于某种原因引发了大量错误,所有错误都在<xutility>标题内。

std::transform效果很好。