---恢復內容開始---html
之前寫代碼總覺用本身寫的東西比較牛逼,vector?stack?爲何不本身實現。後來才認識到這是個幼稚的想法!首先每次都本身實現是一種重複勞動;其次,本身寫的話很難保證沒有bug;效率每每也不如STL。STL的優點不在此贅述,最近使用STL的時候發現調試時,監視器中的內容不忍直視,亂七八糟的,通過一番瞭解才慢慢發現問題所在。在這裏總結一下,也但願能幫到遇到一樣問題的同窗。工具
首先貼出來,我用的vs2015社區版 update3 調試代碼時遇到的問題。item_vec的聲明以下:spa
vector<string> item_vec;debug
當我想查看一下item_vec中的內容時,watch中的內容以下:調試
看到這個,個人心裏基本是崩潰的,這還看個毛線啊。回過頭來想一想,爲何vs顯示的是這些「亂七八糟」的東西?由於這些正是vector對象的成員。想一想一下,vs在提供調試的時候,咱們查看一對象a,vs就應該給我顯示對象a的成員和值,那我想查看vector的內容時,vs就應該像上面這樣顯示,沒有問題。可是回想之前使用stl,調試時顯示的好像不是這種東西,問題出在哪裏?code
一番查找以後,瞭解到這個屬於vs可視化調試的內容。可視化調試大概就是區別於gdb,提供可視化調試界面的功能。強大的vs在想,我怎麼爲STL提供給友好的可視界面,那我爲STL單獨設置一種顯示行不行,vector對象顯示size, capacity, vector中的全部元素列表等等。這樣這個問題貌似就解決了!!!htm
然而這個問題並無這麼簡單,這樣作只能解決STL的顯示問題,若是用戶本身實現了STL功能,或者本身使用了更適合本身的第三方類庫,這個時候STL類的定義都徹底不同了,vs就沒有辦法顯示了。推而廣之,若是任意一個用戶定義的類,並且這個類和STL中的類同樣複雜,而且調試的時候常常須要查看這個類的對象的狀態,這個時候vs就沒法知足要求的。仔細一想這個問題就不能用上面的方案解決。因此微軟提供了更牛叉的解決方案:用戶自定義顯示。對象
大概的想法是這樣的,「我定義的類我作主」,vs提供一種工具,讓你本身來決定怎麼在調試的時候顯示這個類的對象。具體能夠訪問:https://msdn.microsoft.com/zh-cn/library/jj620914.aspx。簡而言之就是,你可使用一種.natvis的文件來定義一個類的對象在調試時的顯示。大概的定義方式以下:blog
<Type Name="std::vector<*>"> <DisplayString>{{ size={_Mylast - _Myfirst} }}</DisplayString> <Expand> <Item Name="[size]" ExcludeView="simple">_Mylast - _Myfirst</Item> <Item Name="[capacity]" ExcludeView="simple">_Myend -_Myfirst</Item> <ArrayItems> <Size>_Mylast - _Myfirst</Size> <ValuePointer>_Myfirst</ValuePointer> </ArrayItems> </Expand> </Type>
這個是微軟給出的樣例,在vs2013中用來定義vector的顯示形式,大概的效果以下:ci
厲害了個人哥,這個就舒服不少嘛!參考微軟官方的指南,你就能夠爲本身的類定義你想要的顯示形式。這樣就在調試代碼的時候就不用加一些爲了查看某些值而寫一些額外的代碼了。
vs在安裝時,STL中的類都有默認的顯示方案,大概就是上面這張圖中的效果。
上面講的是vs自定義類顯示的原理,那爲何個人vs還會有顯示問題,不是有默認的顯示嗎?其實這是vs 社區版update3的一個bug,參考這個連接:https://connect.microsoft.com/VisualStudio/feedback/details/1676171/change-in-c-stl-container-implementation-causes-debug-visualizer-error。bug產生的緣由以下:.natvis文件時XML文件,因此正常是須要加上驗證的,這個驗證文件在C:\Program Files (x86)\Microsoft Visual Studio 14.0\Xml\Schemas\1033\natvis.xsd。可是vs2015社區版update3的這個文件不知道爲何使用的是vs2015RTM版本的xsd文件。致使,vs默認的stl.natvis文件中的一些定義不無經過驗證,相應的內容就沒法生效,在vs看來相應的內容就只能用raw_data的形式顯示。這個問題會在下個版本中解決,目前只能等。上面的鏈接中有人提到了一種解決的偏方,有興趣的同窗能夠嘗試一下,個人vs下沒有偏方中描述的文件,因此沒辦法用。
最後再說一說遇到這種現實問題應該怎麼去確認問題的緣由,若是下次vs再有這種bug,你也能夠本身嘗試去確認bug的緣由。
在vs中能夠設置以原始數據的形式查看。「工具」->「選項」->「調試」->「常規」下能夠設置「在變量窗口中顯示對象的原始數據」,若是但願.natvis生效,須要把這一項取消。
在查看STL(以vector爲例)對象時,能夠查看output窗口,若是.natvis文件解析異常,會報錯。在修改了.natvis文件後能夠在watch窗口中執行.natvisreload命令從新加在.natvis文件。
也能夠爲項目添加.natvis文件,該.natvis文件只會在該項目中生效,而且,修改該.natvis文件會當即生效。參考https://www.zhihu.com/question/41286979。
關於stl.natvis文件,若是須要修改stl.natvis,請注意vs使用的stl版本,不一樣版本stl對容器元素的聲明會不同,如通用的vector顯示:
vs2013:
<Type Name="std::vector<*>" Priority="MediumLow"> <DisplayString>{{ size={_Mylast - _Myfirst} }}</DisplayString> <Expand> <Item Name="[capacity]" ExcludeView="simple">_Myend - _Myfirst</Item> <ArrayItems> <Size>_Mylast - _Myfirst</Size> <ValuePointer>_Myfirst</ValuePointer> </ArrayItems> </Expand> </Type>
vs2015:
<Type Name="std::vector<*>"> <DisplayString>{{ size={_Mypair._Myval2._Mylast - _Mypair._Myval2._Myfirst} }}</DisplayString> <Expand> <Item Name="[capacity]" ExcludeView="simple">_Mypair._Myval2._Myend - _Mypair._Myval2._Myfirst</Item> <Item Name="[allocator]" ExcludeView="simple">_Mypair</Item> <ArrayItems> <Size>_Mypair._Myval2._Mylast - _Mypair._Myval2._Myfirst</Size> <ValuePointer>_Mypair._Myval2._Myfirst</ValuePointer> </ArrayItems> </Expand> </Type>
最後的最後,若是是想vs2015社區版update3這樣的bug,暫時沒法修復時。在watch窗口item_vec[0]會失敗,可使用"&(item_vec.operator[](0)),n",這個表達式能夠查看vector中n個元素。