Я знаю, что это может быть не так полезно, как вы хотели, но я нашел лучший инструмент против сообщений об ошибках шаблона: знание .
Хорошее понимание STL и какего использование поможет вам избежать множества ошибок.Во-вторых, часто сообщения об ошибках относятся к функциям в источнике STL - если у вас есть приблизительное представление о том, как реализован STL, это может быть чрезвычайно полезно для расшифровки того, о чем идет сообщение об ошибке.Наконец, создатели компиляторов знают об этой проблеме и постепенно улучшают вывод сообщений об ошибках, поэтому вам лучше придерживаться последней версии вашего компилятора.
Вот хороший пример неясной ошибки шаблона:
std::vector<std::unique_ptr<int>> foo;
std::vector<std::unique_ptr<int>> bar = foo;
unique_ptr
не копируется, его можно только перемещать.Поэтому попытка назначить вектор unique_ptr другому вектору будет означать, что где-то в исходном коде вектора будет пытаться скопировать уникальный указатель.Следовательно, ошибка будет возникать из кода, который вам не принадлежит, и в результате выдает довольно непрозрачное сообщение об ошибке.Идеальное сообщение об ошибке:
main.cpp (20): невозможно создать 'bar' из 'foo': тип шаблона foo не копируется
Вместо этогоVS2010 выдает следующую ошибку:
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xmemory(48): error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'
1> with
1> [
1> _Ty=int
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\memory(2347) : see declaration of 'std::unique_ptr<_Ty>::unique_ptr'
1> with
1> [
1> _Ty=int
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xmemory(197) : see reference to function template instantiation 'void std::_Construct<std::unique_ptr<_Ty>,const std::unique_ptr<_Ty>&>(_Ty1 *,_Ty2)' being compiled
1> with
1> [
1> _Ty=int,
1> _Ty1=std::unique_ptr<int>,
1> _Ty2=const std::unique_ptr<int> &
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xmemory(196) : while compiling class template member function 'void std::allocator<_Ty>::construct(std::unique_ptr<int> *,const _Ty &)'
1> with
1> [
1> _Ty=std::unique_ptr<int>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\vector(421) : see reference to class template instantiation 'std::allocator<_Ty>' being compiled
1> with
1> [
1> _Ty=std::unique_ptr<int>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\vector(481) : see reference to class template instantiation 'std::_Vector_val<_Ty,_Alloc>' being compiled
1> with
1> [
1> _Ty=std::unique_ptr<int>,
1> _Alloc=std::allocator<std::unique_ptr<int>>
1> ]
1> main.cpp(19) : see reference to class template instantiation 'std::vector<_Ty>' being compiled
1> with
1> [
1> _Ty=std::unique_ptr<int>
1> ]
Просеивая это, есть подсказки.Первый раздел ссылается на частный доступ std::unique_ptr<int>
.Второй раздел, если вы щелкнете по строке исходного текста, указывает на конструктор копирования unique_ptr
, который объявлен под спецификатором private:
.Итак, теперь мы знаем, что пытались скопировать unique_ptr, что запрещено.Разделы 3, 4 и 5 просто указывают на стандартный код - это просто шум.В разделе 6 говорится «смотрите ссылку на экземпляр шаблона класса 'std :: _ Vector_val <_Ty, _Alloc>', который компилируется».Другими словами, эта ошибка произошла в коде шаблона вектора.Последний раздел наиболее интересен: он непосредственно указывает на строку, в которой в вашем собственном исходном коде указано foo
- он выяснил, откуда в вашем собственном исходном коде возникла ошибка!
Итак, добавьте подсказки:
- Он исходит из foo,
- Он исходит из векторного кода,
- Он пытается скопировать unique_ptr, что не разрешено.
- Вывод:вектор пытался скопировать один из своих элементов, что недопустимо.Просмотрите код для
foo
и проверьте, нет ли причин, вызывающих копию.
Поскольку компилятор указал только на объявление foo, если присваивание находится далеко в исходном коде, потребуется некоторая охота.Это, очевидно, не идеально, но я думаю, что этот подход в конечном итоге дает вам больше шансов исправить ошибки в целом.Вы начнете распознавать такой тип дампа ошибок, означающего «вы скопировали unique_ptr».Опять же, я не защищаю это, оно определенно нуждается в улучшении - но я думаю, что в наши дни просто достаточно информации в выводе, что в сочетании с хорошим знанием STL позволяет вам решить проблему.