Я не могу вызывать функции шаблона через функцию вызова GDB - это тоже поможет.
На самом деле, после нескольких попыток кажется, что можно, но трудно расставить точки это правильно.
Рассмотрим следующий код
#include <iostream>
double tripleInput(double x) { return 3 * x; }
template <typename T>
inline T doubleInput(T x) {
return 2 * x;
}
int main(int argc, char *argv[])
{
std::cout << doubleInput(13) << std::endl;
std::cout << doubleInput(1.72) << std::endl;
std::cout << tripleInput(1.72) << std::endl;
return 0;
}
После компиляции с отладочными символами и запуска gdb с исполняемым файлом мы можем сделать
call tripleInput(1.5)
, и gdb вернет 4.5 . Все идет нормально. Однако обратите внимание, что если вы напишете call tri
и нажмете TAB, gdb завершит имя как tripleInput(double)
. После этого вы добавляете (1.5)
и можете запускать как
tripleInput(double)(1.5)
, который будет работать, как и раньше.
Теперь давайте попробуем использовать шаблонную функцию doubleInput
. Это имя шаблона, но только после того, как вы используете шаблон с некоторым типом, компилятор сгенерирует функцию из шаблона. Фактические имена: doubleInput<int>
, doubleInput<double>
, и c. Только версии , которые вы фактически использовали , будут в двоичном файле и могут быть просмотрены gdb.
Теперь давайте попробуем
call doubleInput<double>(1.7)
, и gdb вернет 3.3999999999999999
. Большой! Обратите внимание, что
call doubleInput<double>(double)(1.7)
также работает. Просто помните, что
call doubleInput<int>(1.7)
возвращает 2 вместо 3,3999999999999999, но это имеет смысл.
Итак, ответ состоит в том, что вы можете вызывать экземпляры шаблона, если вы передаете полное имя (используйте TAB для завершения имени).
Просто последнее замечание, если я изменю tripleInput и doubleInput для получения аргумента по ссылке, а не по значению, тогда это не сработает, и я получу ошибка «Попытка взять адрес значения, не находящегося в памяти».
- Проблема теперь в том, что я использую много разных типов многомерных массивов, мне нужно сделать перегрузки для каждого массива
С предыдущим ответом это означает, что вы можете написать один шаблон вместо нескольких реализаций. Только не забудьте позвонить один раз. Даже если вы реализуете несколько функций, вам все равно нужно вызывать их, чтобы компоновщик не удалял их из двоичного файла.
Но для облегчения отладки лучшее решение, безусловно, использует API Python gdb для написания собственных симпатичных принтеров для типов bliz::Array
. Если бы у вас были симпатичные принтеры для блиц-шрифтов и все, что вам нужно, чтобы увидеть blitz::Array
, было p variable_name
. Это всегда будет работать, даже если вы отлаживаете из основного файла (без неполноценного запуска вы не можете вызвать функцию).
К сожалению, я не смог найти ни одной существующей реализации хороших принтеров для блиц, что означает что вам придется написать это самостоятельно.
У меня нет опыта работы с блицем, но я часто использую armadillo , библиотеку C ++ для линейной алгебры и научных вычислений c , и я написал красивые принтеры для броненосцев. См. этот ответ и этот репозиторий , если вам любопытно.
Чтобы написать красивые принтеры, вы должны немного понимать, как тип, для которого вы пишете красивые принтеры хранит свои данные. Вам нужно будет прочитать об этом документацию gdb , но лучше всего посмотреть другие реализации симпатичных принтеров. По крайней мере, так я и сделал.