Какая связь между шаблоном C ++ и типизацией утки? - PullRequest
38 голосов
/ 03 августа 2011

Для меня в шаблоне C ++ использовалась идея печатания на клавиатуре, верно? Означает ли это, что все универсальные типы, на которые имеются ссылки в шаблонном классе или методе, относятся к типу утки?

Ответы [ 7 ]

70 голосов
/ 03 августа 2011

Для меня шаблоны C ++ - это версия типизации утилит во время компиляции. Компилятор скомпилирует, например, Класс и пока ваша утка имеет все необходимые типы, он будет создавать экземпляр класса.

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

13 голосов
/ 03 августа 2011

Ввод утки означает: «если она крякает как утка и ходит как утка, значит, это утка». У нас нет формального определения в компьютерной науке для сравнения C ++ с.

C ++ не идентичен (например) Python, конечно, но они оба имеют концепцию неявно определенных интерфейсов. Интерфейс, необходимый для объекта, используемого в качестве аргумента функции Python, зависит от того, что функция делает с ним. Интерфейс, необходимый для типа, используемого в качестве аргумента шаблона C ++, - это то, что шаблон делает с объектами этого типа. Это сходство, и это основание для оценки шаблонов C ++.

Кроме того, из-за вывода аргументов шаблона в C ++ вы можете попытаться передать любой старый объект, и компилятор выяснит, может ли он создать экземпляр шаблона функции.

Одно отличие состоит в том, что в C ++, если аргумент не крякает, объекты компилятора. В Python только объекты времени выполнения (и только если функция действительно вызывается, если в коде есть условные выражения). Это различие в природе интерфейса, требуемого от объекта / типа - в C ++ либо шаблон требует, чтобы конкретное выражение было допустимым, либо он не требует этого. В Python необходимые допустимые выражения могут зависеть от значений времени выполнения ранее необходимых выражений. Таким образом, в Python вы можете запросить объект, который крякает громко или тихо, и если он крякает громко, ему тоже нужно ходить. В C ++ вы можете сделать это с помощью условного dynamic_cast, и, если том является константой времени компиляции, вы можете сделать это для специализаций шаблонов, но вы не можете использовать статическую типизацию, чтобы сказать, что утка должна ходить только если quack_volume() возвращает loud. И, конечно же, в Python требуемый интерфейс на самом деле не может быть «обязательным» - поведение, если метод отсутствует, вызывает исключение, и в этом случае можно задокументировать и гарантировать поведение вызывающей стороны.

Вам решать, определяете ли вы «типизацию утки», чтобы это различие означало, что в C ++ его нет.

12 голосов
/ 03 августа 2011

Для меня в шаблоне C ++ использовалась идея печатания на клавиатуре, верно?

Нет, шаблоны C ++ используются для реализации общего кода.То есть, если у вас есть код, который может работать с несколькими типами, вам не нужно дублировать его для каждого типа.Такие вещи, как std::vector и std::list, являются очевидными примерами этого в действии.Шаблоны C ++ были использованы для выполнения других задач, но универсальность была изначальным намерением.

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

Нет, они просто "нормальные" типы, как и любой другой тип в C ++.Они просто не известны, пока не будет создан экземпляр шаблона.

Тем не менее, шаблоны могут использоваться для реализации чего-то , например, duck typing.Итераторы являются примером.Рассмотрим эту функцию:

template<class InputIterator, class OutputIterator>
    OutputIterator copy(InputIterator first, InputIterator last,
                        OutputIterator result)
{
    while (first!=last) *result++ = *first++;
    return result;
}

Обратите внимание, что функция copy может принимать аргументы любого типа , поскольку она реализует оператор неравенства, оператор разыменования и приращение постфиксаоператор.Вероятно, это так же близко к типу утки, как и в C ++.

5 голосов
/ 03 августа 2011

Не совсем.Утиные типы (стиль динамического типа) никогда не приведут к ошибкам типа во время компиляции, потому что они просто не имеют никакого типа.С шаблонами у вас нет типов, пока вы не создадите экземпляр шаблона.Как только вы это сделаете, переменные имеют разные типы, и вы действительно получите ошибки во время компиляции.

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

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

4 голосов
/ 03 августа 2011

Да, в некотором роде - например, если у типа X есть методы AddRef(), Release() и QueryInterface() с соответствующими сигнатурами, его можно использовать как COM-объект с шаблоном класса CComPtr.Но это не полная утка - проверка типов по-прежнему обязательна для параметров.

2 голосов
/ 03 августа 2011

Нет, это другая концепция.Утиная типизация - это метод для определения типа контейнера с динамической типизацией.Шаблоны C ++ не динамически типизированы, они создаются с определенным типом.

1 голос
/ 03 августа 2011
...