Расхождение std :: iterator_traits между libstdc ++ и libStack Overflow

Дано:

struct Iter {
using value_type = int;
using difference_type = int;
using reference = int;
using pointer = int;
using iterator_category = int;
};

Следующее прекрасно работает с libstc ++, но не компилируется с libc ++ 5.0.0:

#include <iterator>
#include <type_traits>
static_assert(
std::is_same<
std::iterator_traits<Iter>::iterator_category,
Iter::iterator_category
>::value, "");

С ошибкой:

ошибка: нет члена с именем ‘iterator_category‘ в ‘std::__1::iterator_traits<Iter>
std::is_same<std::iterator_traits<Iter>::iterator_category, Iter::iterator_category>::value, "");

Статическое утверждение успешно выполняется, если Iter::iterator_category является одной из стандартных категорий ввода, например, std::input_iterator_tag,

ИМХО, он не должен потерпеть неудачу, потому что проект C ++ заявляет в [Iterator.traits] # ​​2:

Если Итератор имеет действительный ([Temp.deduct]) типы членов difference_­type, value_­type, pointer, reference, а также iterator_­category, iterator_­traits<Iterator> иметь в качестве публично доступных членов:

using difference_type   = typename Iterator::difference_type;
using value_type        = typename Iterator::value_type;
using pointer           = typename Iterator::pointer;
using reference         = typename Iterator::reference;
using iterator_category = typename Iterator::iterator_category;

Иначе, iterator_­traits<Iterator> не должен иметь членов с любым из вышеперечисленных имен.

Кто-нибудь может объяснить, является ли это ошибкой реализации или почему мои ожидания ошибочны?

4

Решение

У нас также есть, в [std.iterator.tags]:

Зачастую для специализации шаблона функции желательно выяснить, какая категория является наиболее конкретной категорией аргумента итератора, чтобы функция могла выбрать наиболее эффективный алгоритм во время компиляции. Чтобы облегчить это, библиотека вводит классы тегов категорий, которые используются как теги времени компиляции для выбора алгоритма. Они есть: input_­iterator_­tag, output_­iterator_­tag, forward_­iterator_­tag, bidirectional_­iterator_­tag а также random_­acces_­iterator_­tag, Для каждого итератора типа Iterator, iterator_­traits<Iterator>​::​iterator_­category должен быть определен как наиболее конкретный тег категории, который описывает поведение итератора.

namespace std {
struct input_iterator_tag { };
struct output_iterator_tag { };
struct forward_iterator_tag: public input_iterator_tag { };
struct bidirectional_iterator_tag: public forward_iterator_tag { };
struct random_access_iterator_tag: public bidirectional_iterator_tag { };
}

int не один из тех тегов, так iterator_traits<Iter>::iterator_category не могу вернуть тебя int, Я хотел бы предположить, что наличие недопустимой категории итераторов просто нарушает предварительные условия iterator_traits — это не обязательно означает, что библиотека должна дать сбой, но это также не означает, что сбой является ошибкой библиотеки.

Тем не менее, эти предварительные условия не прописаны в [итераторах] так явно, как в других частях раздела библиотеки. Поэтому я склонен предположить, что обе библиотеки верны, но подход libc ++ не определяет псевдонимы членов в iterator_traits<Iter> скорее всего лучше.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]