Подтвердить что ты не робот

Как вы отлаживаете сильно шаблонный код на С++?

Мне очень сложно понять, что не так с моим кодом при использовании метапрограмм шаблонов С++. Возможно, я просто не очень хорошо понимаю сообщения об ошибках, но, насколько мне известно, я не могу прибегать к тому, чтобы печатать заявления или точки останова, чтобы выяснить, что происходит.

Какие советы или рекомендации вы можете предложить, пытаясь понять, почему что-то не компилируется, кроме как просто выбирать код вручную и надеяться, что он придет ко мне?

4b9b3361

Ответ 1

Для STL, по крайней мере, есть доступные инструменты, которые будут выводить более удобные для пользователя сообщения об ошибках. См. http://www.bdsoft.com/tools/stlfilt.html

Для шаблонов, отличных от STL, вам просто нужно узнать, что означают ошибки. После того, как вы видели их дюжину раз, становится легче догадаться, в чем проблема. Если вы разместите их здесь, возможно, кто-то может помочь вам разобраться.

Ответ 2

Вы можете попробовать использовать новый компилятор. Если вы используете Visual С++ 6.0, переключитесь на 9.0, и вы увидите огромный скачок в полезности ошибок компилятора.

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

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

Ответ 3

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

Ответ 4

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

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

И последнее, но не менее важное: STLfilt чрезвычайно полезен, и вы можете изменить его самостоятельно, чтобы он соответствовал вашим потребностям, а также возможно.

Но самое главное - стараться не использовать метапрограммирование везде. Это сложно, поэтому используйте его только тогда, когда вам это действительно нужно.

Ответ 5

Это должно помочь вам, я думаю.

http://www.bdsoft.com/tools/stlfilt.html

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

Ответ 6

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

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

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

Кроме того, либеральное использование static_assert (или BOOST_STATIC_ASSERT) может помочь в значительной степени, предоставляя проверки работоспособности

Ответ 7

Вы привыкаете к нему со временем, и, к сожалению, если вы планируете использовать С++, вам нужно это сделать. Потому что некоторые библиотеки, такие как VC9, имеют хорошие сообщения об ошибках, но как только вы переходите на GCC или какой-то другой компилятор, сообщения уходят. И даже VC9 не поможет вам, когда у вас есть ошибки из какой-либо библиотеки, написанной кем-то другим, или самим собой во время поздней ночи, даже некоторые библиотеки Boost не так уж дружелюбны. Просто потому, что не каждый автор постарался понять, когда возникает ошибка, и это еще более распространено с новыми библиотеками (которые имеют наибольшее количество ошибок и меньше помощи).

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

Использование инструментов поможет вам в начале, но повредит вам в долгосрочной перспективе. И поскольку проблема присуща С++, она не уходит в любой день в ближайшее время. И эти стены ошибок, скорее всего, будут с нами, пока С++ больше не будет использоваться. Поэтому инструменты просто режут вам зубы, когда вам нужно их выжить. Если вы планируете скоро покинуть С++, пожалуйста, не стесняйтесь использовать их. В настоящее время я могу нормально понимать эти сообщения с 400-строчными сообщениями одним взглядом, поэтому они кристально чисты для моих глаз, но это не благодаря каким-либо инструментам.

Как и во всем, особенно на С++, требуется опыт и обучение.

Ответ 8

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

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

Если вы затем следуете советам из других ответов, особенно в отношении утверждений compile_time, вам будет легче найти источник проблем.

Ответ 9

Templight: Отладчик и профайлер метапрограмм шаблона С++

Ответ 10

Metashell - отличный инструмент для отладки шаблонов. С онлайн-режимом!