std::unique_ptr
хороши, но я нахожу их менее удобными при отладке в DDD или же GDB.
Я использую красивые принтеры GDB, которые являются частью GCC (например, /usr/share/gcc-4.8.2/python/libstdcxx/v6/printers.py
). Это большая победа для читабельности, например:
$ print pTest
std::unique_ptr<MyType> containing 0x2cef0a0
Однако разыменование указателя не работает:
$ print *pTest
Could not find operator*.
Когда мне нужно получить доступ к значению, я должен вручную скопировать указатель и привести его к правильному типу, например:
print *((MyType*) 0x2cef0a0)
Если процесс все еще выполняется, эта версия работает (все еще безобразно, но лучше):
print *pTest.get() // will not work if analyzing a core dump
Прямой подход к Display *pTest
в DDD тоже не работает. Это приводит только к следующей ошибке:
<error: Could not find operator*.>
Есть ли способ отладки кода C ++ 11 с unique_ptr в DDD (не нарушая рабочий процесс, как я делаю с моими громоздкими обходными путями)?
Я не боюсь использовать команды GDB, но интеграция DDD будет плюсом. Например, следование указателям в структурах данных путем двойного щелчка по ним часто происходит быстрее, чем ввод текста.
Я уже пытался уронить симпатичный принтер, но он также не оптимален. Лучшее, что я мог придумать, это следующее:
print pTest._M_t->_M_head_impl
Эта проблема на самом деле не связана с C ++ 11, unique_ptr или красивой печатью. Проблема в том, что gcc не генерирует код для std :: unique_ptr :: operator *, который может быть вызван gdb для разыменования unique_ptr. Если вы, например, добавить *pTest;
к вашему коду, тогда GDB выполняет разыменование.
Аналогичная проблема описана в посте SO Как «напечатать» / оценить функции шаблона c ++ в gdb. Почти такая же проблема описана для auto_ptr в https://sourceware.org/ml/archer/2012-q1/msg00003.html. Если я правильно понимаю поток, одним из обходных путей будет исправление симпатичного принтера, а также распечатка разыменованного указателя при печати unique_ptr. Отчет об ошибке GDB можно найти на http://sourceware.org/bugzilla/show_bug.cgi?id=12937.
GDB Wiki на https://sourceware.org/gdb/wiki/STLSupport описывает более красивые решения для печати, которые могут иметь другие обходные пути.
Редактировать: более элегантное решение, заставляющее компилятор генерировать код для всех шаблонов-членов, включая оператор *, заключается в явном создании экземпляра класса:
template class std::unique_ptr<MyType>;
Других решений пока нет …