Каковы недостатки использования шаблонов?

некоторые из недостатков были бы

  1. синтаксис сложного
  2. компилятор генерирует дополнительный код

11 ответов


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


Хм, как насчет...

3: они могут быть медленными для компиляции

4: они заставляют вещи вычисляться во время компиляции, а не во время выполнения (это также может быть преимуществом, если вы предпочитаете быструю скорость выполнения гибкости выполнения)

5: старые компиляторы C++ не обрабатывают их или не обрабатывают их правильно

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


Шаблоны предоставляют вашу реализацию клиентам вашего кода, что затрудняет поддержание вашего ABI, если вы передаете шаблонные объекты на границах библиотеки.


единственным реальным недостатком является то, что если вы делаете какую-либо крошечную синтаксическую ошибку в шаблоне (особенно тот, который используется другими шаблонами), сообщения об ошибках не будет полезно... ожидайте пару страниц почти непригодных для использования ошибок msgs; -). Дефект компиляторов очень специфичен для компилятора, и синтаксис, хотя и уродливый, на самом деле не "сложный". В целом , хотя-несмотря на огромную проблему с правильной диагностикой ошибок-шаблоны по-прежнему на одна лучшая вещь о C++, единственное, что может соблазнить вас использовать C++ над другими языками с более низкими реализациями дженериков, такими как Java...


до сих пор никто, кажется, не упомянул главный недостаток, который я нахожу с шаблонами:читабельность кода падает!

Я не имею в виду вопросы синтаксиса -- да синтаксис уродлив, но я могу простить это. Я имею в виду следующее: Я нахожу, что с невиданным ранее не шаблонным кодом, каким бы большим ни было приложение, если я начну с main() обычно я могу декодировать широкие штрихи того, что делает программа без проблем. И код, который просто использует vector<int> или подобное меня нисколько не беспокоит. Но как только код начинает определять и использовать свои собственные шаблоны для целей, выходящих за рамки простых типов контейнеров, понятность быстро исчезает. и это имеет очень негативные последствия для обслуживания кода.

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

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


несвязанная трудность с шаблонами заключается в том, что отладчики по-прежнему испытывают трудности с естественным отображением содержимого контейнеров STL (по сравнению, скажем, с массивами c-стиля).


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


меньше людей понимают их, epsecially на уровне метапрограммирования, поэтому меньше людей могут поддерживать их.


когда вы используете шаблоны, ваш компилятор генерирует только то, что вы фактически используете. Я не думаю, что есть какие-либо недостатки в использовании мета-программирования шаблонов C++, кроме времени компиляции, которое может быть довольно длинным, если вы использовали очень сложные структуры, как библиотеки boost или loki.


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

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


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


Я использовал шаблоны иногда на протяжении многих лет. Они могут быть удобными, но с профессиональной точки зрения, я отклоняюсь от них. Две из причин:--1-->

1.

необходимость либо a.) предоставьте определения функций (а не только объявления) "исходный" код коду "где используется" или b.) создайте фиктивный экземпляр в исходном файле. Это необходимо для компиляции. Вариант а) можно сделать, определив функции в заголовке или фактически включив СРР.

одна из причин, по которой мы допускаем заголовки в C++ (по сравнению с C#, например), заключается в отделении "интерфейса" от "реализации". Ну, шаблоны, кажется, несовместимы с этой философией.

2.

функции, вызываемые экземпляром параметра типа шаблона, могут не выполняться во время компиляции, что приводит к ошибкам ссылок. Е. Г. T пример; пример.CompilerDoesntKnowIfThisFunctionexistsont(); Это "свободные" ПО МОЕМУ.

решения:

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

Если тип неважен, например, vector, то как насчет просто использования "object". C++ не предоставил ключевое слово "object", и я предложил Dr.Bjarne Stroustrup, что это было бы полезно, особенно сказать компилятору и людям, читающим код, что тип не важен (для случаев, когда это не так). Я не думаю, что C++11 имеет это, возможно, C++14 будет?