これはあなたが望むほど役に立たないかもしれませんが、テンプレートのエラー メッセージに対する最良のツールはknowledgeであることがわかりました。
STL とその使用方法をよく理解することは、そもそも多くのエラーを回避するのに役立ちます。第 2 に、エラー メッセージは STL ソース内の関数を参照することがよくあります。STL がどのように実装されているかを大まかに把握している場合、これはエラー メッセージの内容を解読するのに非常に役立ちます。最後に、コンパイラ メーカーはこの問題を認識しており、エラー メッセージの出力を徐々に改善しているため、最新バージョンのコンパイラを使用することをお勧めします。
以下は、あいまいなテンプレート エラーの良い例です。
std::vector<std::unique_ptr<int>> foo;
std::vector<std::unique_ptr<int>> bar = foo;
unique_ptr
はコピー不可で、移動のみ可能です。したがって、unique_ptr のベクターを別のベクターに割り当てようとすると、ベクター ソース コードのどこかで一意のポインターをコピーしようとすることになります。したがって、エラーは自分のものではないコードから発生し、結果としてかなり不透明なエラー メッセージがスローされます。理想的なエラー メッセージは次のようになります。
main.cpp(20): 'foo' から 'bar' を作成できません: 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>
。ソース行までクリックすると、2 番目のセクションはunique_ptr
、指定子の下で宣言されている のコピー コンストラクターを指しprivate:
ます。これで、許可されていない unique_ptr をコピーしようとしたことがわかりました。セクション 3、4、および 5 は定型コードを示しているだけです。これは単なるノイズです。セクション 6 には、「コンパイルされているクラス テンプレートのインスタンス化 'std::_Vector_val<_Ty,_Alloc>' への参照を参照してください」と記載されています。つまり、このエラーは vector のテンプレート コードで発生しました。最後のセクションは最も興味深いものです。これfoo
は、独自のソース コードで宣言している行を直接指しています。これにより、独自のソース コードのどこからエラーが発生したかがわかります。
したがって、手がかりを追加します。
- それはfooに由来し、
- それはベクトルコードに由来し、
- 許可されていない unique_ptr をコピーしようとしています。
- 結論: ベクターはその要素の 1 つをコピーしようとしましたが、これは許可されていません。コードを
foo
確認して、コピーの原因となっているものがないか確認します。
コンパイラは foo の宣言のみを指すため、代入がソース コード内で遠く離れている場合、ハンティングが必要になります。これは明らかに理想的ではありませんが、最終的にはこのアプローチにより、一般的に間違いを修正する可能性が高くなると思います。この種のエラー ダンプが「unique_ptr をコピーした」ことを意味することを認識するようになります。繰り返しますが、私はそれを擁護しているわけではありません。間違いなく改善が必要ですが、最近では、STL の十分な知識と組み合わせて問題を解決できる十分な情報が出力に含まれていると思います。