Итератор шаблона класса и сокрытие информации

Предполагая, что у нас есть реализация шаблонного класса для матрицы. Я хочу представить матрицу std::vector типа T,

Теперь я хочу вернуть итератор матрицы, вернув итератор вектора. Для этого я увидел, что с помощью ключевого слова typename требуется в public раздел:

typedef typename std::vector<T>::iterator iterator.

Во-первых, я не понимаю, почему typename требуется здесь.

Во-вторых, каждый может видеть, что я использую std::vector представлять матрицу. Что я могу сделать, чтобы предотвратить раскрытие этой информации.

Как я могу достичь этой цели, не раскрывая матричное представление?

3 ответа

Решение

Во-первых, вам нужно имя типа, поскольку вы используете зависимый тип. для получения дополнительной информации см. Где и почему я должен поставить ключевые слова "template" и "typename"?

Для второй части вы можете сделать две typedefs. Один в частном разделе, который

typedef typename std::vector<T> container;

И тогда в публичном разделе вы могли бы сделать

typedef typename container::iterator iterator;

И вы можете увидеть, как это компилируется здесь

Во-первых, я не понимаю, почему typename включено сюда.

typename сообщает компилятору, что iterator это действительно тип, а не член, например, который будет выглядеть точно так же. Вы должны уточнить это при работе с шаблонами, потому что в общем случае на этом этапе компилятору не хватит информации, чтобы заметить разницу.

Во-вторых, каждый может видеть, что я использую вектор для представления матрицы, что я могу сделать, чтобы предотвратить раскрытие этой информации.

Хотя каждый может видеть, что вы используете вектор, это не является коммерческой тайной. Вы предоставляете typedef для использования внешним миром, подчеркивая, что вектор - это просто деталь реализации, и если они этого не делают, они заслуживают того, что приходит, по моему мнению.

Чтобы подчеркнуть это, vector<T>::iterator также является typedef, и в некоторых компиляторах это означает разные вещи, когда вы компилируете с разными флагами. Иногда вы можете найти его и использовать T* везде, но когда код в конечном итоге сломается, вы действительно будете жаловаться на разработчиков стандартной библиотеки?

Я не думаю, что вы могли бы скрыть это лучше: компилятор должен знать, что такое итератор.

Вы должны включить typename здесь, потому что есть предполагаемый тип, T, подарок. Об этом спрашивали и отвечали здесь.

Что касается вашего второго вопроса, вы на самом деле не выставляете здесь представление о классе; пользователь вашего класса не должен понимать, что базовое представление Matrix является std::vector для того, чтобы использовать свой класс. Информация на самом деле будет доступна только в том случае, если пользователь попытается ее найти (например, из-за ошибки компиляции). Даже если вы определили свой собственный итератор, пользователь все равно может просто посмотреть на ваш исходный код.

Наконец, если вы используете C++11, лучший способ сделать то же самое - использовать псевдонимы:

using iterator = typename std::vector<T>::iterator;

Нет непосредственного преимущества в этом случае, но хорошо, чтобы войти в эту привычку.

Другие вопросы по тегам