Я столкнулся с некоторыми досадными проблемами с константностью в некотором шаблонном коде, которые в конечном итоге сводятся к следующему наблюдению: по какой-то причине, учитывая тип контейнера STL-ish типа T, const typename T::pointer
на самом деле, кажется, не получить постоянный тип указателя, даже если T::pointer
эквивалентно T::value_type*
.
Следующий пример иллюстрирует проблему. Предположим, у вас есть шаблонная функция, которая принимает контейнер, который должен соответствовать требованиям концепции контейнера произвольного доступа STL.
template <class Container>
void example(Container& c)
{
const typename Container::pointer p1 = &c[0]; // Error if c is const
const typename Container::value_type* p2 = &c[0];
}
Тогда, если мы передадим эту функцию константному контейнеру ...
const std::vector<int> vec(10);
example(vec);
... мы получаем неверное преобразование из const int*
в int*
. Но почему const typename Container::pointer
не совпадает с const int*
в этом примере?
Обратите внимание, что если я изменю const typename Container::pointer
на просто typename Container::const_pointer
, то он прекрасно скомпилируется, однако, насколько я могу судить, conde_pointer typedef является расширением (я не вижу его упомянутым в стандартных требованиях контейнера C ++ (23.5, таблица 65)), и поэтому я не хочу его использовать.
Так как же я могу получить общий, правильный константный тип указателя из контейнера T? (Я действительно не могу понять, как это сделать, не используя boost :: mpl :: if_ вместе с type_traits, чтобы проверить, является ли контейнер постоянным ... но должен быть менее подробный способ сделать это)
Редактировать: В случае, если это имеет значение, я использую gcc 4.3.2 для компиляции.