Применение общих имен методов - PullRequest
2 голосов
/ 15 апреля 2011

Примечание. Это дополнительный вопрос к this.

У меня есть группа шаблонных классов, которые делают совершенно разные вещи совершенно разными способами, используя совершенно разные типы данных.Однако они имеют общие имена методов.Например, Get(), Set(), Resize() и т. Д. Являются допустимыми методами для каждого из рассматриваемых классов.Кроме того, они принимают аргументы в том же порядке.Это позволяет обобщенным функциям, не являющимся друзьями, не являющимися членами, работать с каждым из классов.Упрощенный пример:

template <typename Class, typename Datatype>
void Insert(const Class<Datatype>& Object, const std::size_t Index, const Datatype Value)
{
    Object.Resize(Object.Size() + 1);
    for (std::size_t CurrentIndex = Object.Size() - 1; CurrentIndex > Index; CurrentIndex--)
    {
        Object.Set(CurrentIndex, Object.Get(CurrentIndex - 1));
    }
    Object.Set(Index, Value);
}

Сейчас я просто полагаюсь на свою память, чтобы правильно определить все соответствующие методы.Есть ли способ заставить компилятор принудительно определить правильные методы?Если нет, есть ли лучший способ сделать это?

Ответы [ 4 ]

3 голосов
/ 15 апреля 2011

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

К сожалению, сообщения об ошибках компиляторов для неосуществимых шаблонов часто трудно расшифровать.

Требования к типу можно задокументировать в комментариях. Посмотрите, как стандарт C ++ определяет требования к типам, такие как Assignable, CopyConstructible, EqualityComparable, LessThanComparable и требования к типам в стандартных контейнерах.

3 голосов
/ 15 апреля 2011

То, что вы ищете, называется " concept " и раньше было функцией в C ++ 0x, но было исключено из нового стандарта.

Существуют некоторые реализации для C ++ 03, но они сложнее в использовании и могут не стоить проблем. например Проверка концепции повышения

У gcc также есть опция --enable-concept-check, хотя я не совсем уверен, как это работает с кодом пользователя.

2 голосов
/ 15 апреля 2011

Компилятор принудительно применяет правильный интерфейс, если не скомпилирует любой вызов несуществующей функции; возможно проблема в том, что сообщения об ошибках слишком загадочны?

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

Тогда, если аргумент шаблона происходит от этого базового класса, сбой в реализации требуемой функции вызовет ошибку связи (из-за попытки вызвать функции базового класса, которые не определены). Скорее всего, это будет легче диагностировать, чем типичная ошибка компиляции, связанная с шаблоном.

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

0 голосов
/ 15 апреля 2011

Вы можете использовать интерфейс.

См. Этот вопрос: Как вы объявляете интерфейс в C ++?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...