Соответствующее использование шаблона - PullRequest
2 голосов
/ 06 февраля 2012

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

template <class InputIterator>
void Object::add(InputIterator first, InputIterator last) { ... }

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

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

Ответы [ 2 ]

5 голосов
/ 06 февраля 2012

К сожалению, C ++ в настоящее время не позволяет вам кратко кодифицировать такую ​​информацию.

C ++ 11 должен был решить эту проблему с помощью концепций , но они были выброшены перед выпуском из-за некоторых концептуальных (хе) недостатков (, которые в пока что решено , насколько я знаю).

Но вы все равно можете предоставить такие понятия, используя статические утверждения и черты типа. Например, C ++ 11 позволяет написать следующий код:

template <class InputIterator>
void Object::add(InputIterator first, InputIterator last) {
    static_assert(
        std::is_same<
            typename std::remove_cv<
                typename std::iterator_traits<InputIterator>::value_type
            >::type,
            std::string>::value,
        "InputIterator must be of iterator type");
    …
}

Тем не менее, предполагается, что InputIterator является допустимым типом итератора. Поскольку нет признака is_iterator и никакого осмысленного способа реализовать это (насколько я знаю), за исключением проверки того, что выполняются все необходимые операции входного итератора , это делает его гораздо более сложным, чем он. теоретически может быть.

0 голосов
/ 06 февраля 2012

Как упоминал Конрад Рудольф, вы можете потерять конструкцию шаблона и просто иметь сигнатуру метода add с итераторами строк. Или сохранить шаблонную конструкцию. Реализация add может заставить аргументы быть строковыми итераторами тем, что вызывается. Мол,

add(InputIterator first, InputIterator last) {
if ( first.begin == last.end) { do something }
}

Это не потребует, чтобы первый и последний были строковыми итераторами, но компилятор будет жаловаться, если first.begin и / или last.end недопустимы.

...