#c #stl #stl-algorithm
#c #stl #stl-алгоритм
Вопрос:
В настоящее время я просматриваю некоторый код, который может быть скомпилирован на более новых версиях GCC, но не на старых. В моем случае я использую std::back_inserter
для std::copy
переноса некоторых данных из одной структуры данных в пользовательскую структуру данных. Однако, если я забуду typedef value_type amp; const_reference
typedef в этой пользовательской структуре данных, это не будет компилироваться в GCC 4.4. Тот же код компилируется и отлично выполняется в GCC 4.5.
В чем разница между этими двумя версиями компилятора, которая заставляет код компилироваться в одной версии, но не в другой. Я бы предположил, что это как-то связано с реализацией C 11, которая была намного менее полной в GCC 4.4. Вероятно, что-то с decltype
или другим новым ключевым словом C 11, я бы предположил.
Также корректен ли этот код, если я использую std::back_inserter
без определения const_reference
типа? Обычно я думал, что нужно реализовать полный набор typedefs ( value_type
, reference
const_reference
и т.д.), Чтобы быть совместимым с библиотекой STL-algorithms? Или я могу с уверенностью предположить, что если мой код компилируется в этом случае, я не вызываю ничего опасного (например, семантику перемещения, которая разрушила бы мою другую структуру данных).
Комментарии:
1. Для справки (чтобы помочь новичкам вроде меня сэкономить время): После того, как я добавил
typedef Tamp; reference; typedef const Tamp; const_reference;
в свою структуру данных, ошибка c2039 для back_inserter исчезла.
Ответ №1:
В стандарте (1998) говорится, что это std::back_insert_iterator
необходимо Container::const_reference
. В «24.4.2.1 классе шаблона back_insert_iterator», [lib.back.insert.iterator], говорится:
back_insert_iterator<Container>amp;
operator=(typename Container::const_reference value);
Стандарт 2011 требует только Container::value_type
,
back_insert_iterator<Container>amp;
operator=(const typename Container::value_typeamp; value);
back_insert_iterator<Container>amp;
operator=(typename Container::value_typeamp;amp; value);
Итак, чтобы быть совместимым с обеими версиями стандарта C , определите обе value_type
и const_reference_type
.
Как в GCC 4.4.6, так и в 4.5.1, определение operator=
идентично ( libstdc -v3/include/bits/stl_iterator.h
):
back_insert_iteratoramp;
operator=(typename _Container::const_reference __value)
{
container->push_back(__value);
return *this;
}
и я получаю одинаковую ошибку с обоими компиляторами, возможно, вам нужно дважды проверить, используете ли вы правильные версии компилятора.
Комментарии:
1. Спасибо за разъяснение. В версии 4.5.2 это работает без типа const_reference, как я только что подтвердил. 4.4.4 все еще нуждается в этом.
2. @LiKao, в последних GCC совместимость с библиотекой C 0x включена по умолчанию. GCC4.5.2 немного более совместим :), чем GCC 4.4, в том смысле, что он использует
const_reference
только тогда, когда совместимость отключена, тогда как 4.4 использует ее безоговорочно.3. @chill: Цитирую документацию текущей версии gcc :
The default, if no C language dialect options are given, is -std=gnu 98.
. Итак, вы уверены в том, что говорите?
Ответ №2:
Причина, по которой вам нужно const_reference
определить для вашей структуры данных, заключается в том, что оператор присваивания в GCC 4.4 для типа аргумента lvalue в std::back_insert_iterator
классе определен как:
template<class Container>
back_insert_iterator<Container>amp;
back_insert_iterator<Container>::operator=
(typename Container::const_reference value);
Таким образом, const_reference
должен быть разрешимый идентификатор в вашем классе-введите, чтобы правильно создать экземпляр оператора присваивания в std::back_insert_iterator
шаблоне класса.
В GCC 4.5 это определение оператора присваивания для аргументов lvalue было изменено на
template<class Container>
back_insert_iterator<Container>amp;
back_insert_iterator<Container>::operator=
(const typename Container::value_typeamp; value);
для поддержки новой спецификации C 11. Поскольку ваш код корректно компилируется с GCC 4.5, я предполагаю, что вы должны value_type
правильно определить свою структуру данных.