Путаница в отношении std :: transform - преобразование std :: map value_type :: second to std :: vector

Привет, кто-нибудь скажет мне, почему 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>() );
</elementsmap::value_type></elementarray></cvertexsemantic::type,></cfvfelementptr>

Все, что я пытаюсь сделать, это

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
};
</container>
3 ответа

Проблема заключается в ElementsMap::value_type::second_type - ElementArray. То есть вы пытаетесь вставить экземпляры ElementArray в ElementArray, который действительно содержит экземпляры CFVFElementPtr.

Обновление: изменение объявления operator= из

this_type& operator = (typename const_reference value)

в

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

почти работает. За исключением того, что ни VS 2010, ни GCC 4.6.1 не предоставляют перегрузку vector::insert которая возвращает итератор. Вероятно, вам понадобится новый компилятор, если вы хотите, чтобы ваша вставка ranged вернула итератор для замены iter.

Изменение реализации, которое нужно всегда вставлять в конец, а именно

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

in operator= компилируется с GCC 4.6.1 (и, конечно же, вы можете удалить все ссылки на iter в своем классе итератора).


Вы можете подумать об использовании функтора, который может добавлять элементы в ваш целевой массив вместе с std::for_each для 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));


Я нашел ответ, поблем был с моим пользовательским итератором. Правильный, который работает

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);
}
</container></container></container>

Однако я должен предупредить, что если вы используете это в Visual Studio 2010, вам придется реализовать SGI-форму std :: transform. Версия, которая поставляется с VS2010, почему-то вызывает множество ошибок, все из которых лежат в заголовке .

Этот std :: transform работает отлично.

licensed under cc by-sa 3.0 with attribution.