Boost 是一個相當強大好用的 C++ library,一直都沒辦法把它摸透。最近在用的時候遇到神秘的問題,追了一下還是沒辦法完全理解,先筆記下來也許會有什麼進展(或是得到有緣人的提點:P)。
首先是我的開發環境:Ubuntu 10.04 64-bits, GCC 4.4.3, Boost 1.40 (libboost-dev 1.40.0.1)
我其實是在 #include <boost/graph/adjacency_list.hpp>
的地方遇到問題的,他出現的 warning message 如下:
warning: #warning This file includes at least one deprecated or antiquated header which may be removed without further notice at a future date. Please use a non-deprecated interface with equivalent functionality instead. For a listing of replacement headers and interfaces, consult the file backward_warning.h. To disable this warning use -Wno-deprecated.
這訊息事實上是在 <backward/backward_warning.h>
這個檔案裡寫死的,至於為什麼會出現這個訊息呢?是因為 <boost/graph/adjacency_list.hpp>
使用了 <backward/hash_set>
這個檔案,他不被建議使用….(deprecated)。相信 boost 會使用 <hash_set>
也是歷史的塵埃吧?根據該 warning 檔案裡面的敘述,建議使用 <unordered_set>
取代 <hash_set>
,以上是關於這個部份的發現。
另一方面,boost 本身有相關的設定可以做,尋找的開端是 <boost/config.hpp>
,從它開始追可以追蹤到 <boost/config/suffix.hpp>
這個檔案,在我這個版本的 298 行有這樣的一段程式碼:
#if defined(BOOST_HAS_HASH) && !defined(BOOST_HASH_SET_HEADER)
# define BOOST_HASH_SET_HEADER <hash_set>
#endif
網路上找到的這個解答也是說明可以藉由 define BOOST_NO_HASH
來 disable hash 的支援…但是相對來說,就無法在 adjacency_list
中使用 hash_setS
或是 hash_mapS
了。
實際嘗試過後,define BOOST_NO_HASH
的確可以避免該 warning message 的產生,但是這明顯不是最好的作法,所以我嘗試在 boost 相關的 inclusion 之前先這麼做:
#define BOOST_HASH_SET_HEADER <unordered_set>
這麼做是來自於 <boost/graph/adjacency_list.hpp>
中的第20行(一樣是在我的版本):
// TODO: Deprecating this requires some cooperation from Boost.Config. It's not
// a good idea to just refuse the inclusion because it could break otherwise
// functioning code.
#if !defined BOOST_NO_HASH
# ifdef BOOST_HASH_SET_HEADER
# include BOOST_HASH_SET_HEADER
# else
# include <hash_set>
# endif
#endif
想像中的一切是多麼完美……只要我 define 了 BOOST_HASH_SET_HEADER
,那他就不會去 include 那討厭的 <hash_set>
,而是使用我要他 include 的 <unorder_set>
了!然而天不從人願(好爛的轉折語= =),即使我這麼做:
#define BOOST_HASH_SET_HEADER <unordered_set>
似乎還是會被 <boost/config.hpp>
給改回來= =a
最神奇的是我找不到他在哪裡改的XD
我自己的引用方式如下:
#define BOOST_HASH_SET_HEADER <unordered_set>
#include <boost/bind.hpp>
#include <boost/graph/adjacency_list.hpp>
那個 bind.hpp
會 include config.hpp
:(
如果這麼做:
#include <boost/bind.hpp>
#define BOOST_HASH_SET_HEADER <unordered_set>
#include <boost/graph/adjacency_list.hpp>
會造成 BOOST_HASH_SET_HEADER
的重複定義,因為 config.hpp
裡面呼叫 suffix.hpp
會去 define 這玩意兒….好吧,那就只好來硬的:
#include <boost/bind.hpp>
#undef BOOST_HASH_SET_HEADER
#define BOOST_HASH_SET_HEADER <unordered_set>
#include <boost/graph/adjacency_list.hpp>
結果噴出來的訊息我也只能心服口服了…..
error: #error This file requires compiler and library support for the upcoming ISO C++ standard, C++0x. This support is currently experimental, and must be enabled with the -std=c++0x or -std=gnu++0x compiler options.
這個訊息來自 <unordered_set>
……要用 C++0x 是吧…….所以說,我………放棄了= =a
目前暫時的結論就是,先 define BOOST_NO_HASH
吧,等到 boost (或是說 BGL?) 出了新版,還有 GCC 預設支援 C++0x 的時候,這問題應該連改都不用改就解決了XD"
有興趣的朋友們可以嘗試看看強迫使用 C++0x 配合 <unordered_set>
看看會不會順利編譯唷 :D
PS. 歡迎把你的經驗分享給我 :P
Last modified on 2011-09-26