2009-10-08 31 views
3

在MFC打開的情況下編譯VS2008中的以下代碼時出現警告。升壓版本1.39如何擺脫在VS2008中由boost :: flyweight產生的C4800警告


include "boost/flyweight.hpp" 
include "boost/flyweight/key_value.hpp" 
class Foo 
{ 
    public: 
    Foo(const CString& item) : mfoo(item) {} 
    const CString& getkeyvalue() const {return mfoo;} 
    private: 
    const CString mfoo; 
}; 
struct Conversion 
{ 
    const CString& operator() (const Foo& item) const {return item.getkeyvalue();} 
}; 

using namespace boost::flyweights; 
flyweight<key_value<CString, Foo, Conversion>, tag<Foo> > flyweight_test; 

在上面的代碼中的最後一行產生警告

d:\工作\源碼\ boost1390 \提高\官能\散列\ extensions.hpp(72):警告C4800:'const wchar_t *' :強制值爲bool'true'或'false'(性能警告)
d:\ work \ sourcecode \ boost1390 \ boost \ functional \ hash \ extensions.hpp(71):編譯類模板成員函數size_t boost::hash<T>::operator()(const T &) const
[
T=ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t>>
]
d:\工作\源碼\ boost1390 \升壓\ multi_index \ hashedindex.hpp(1159):見參考文獻類模板實例 '升壓::散列<Ť>' 被與
[
T=ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t>>
編譯]

此警告的推移而上,通過散列工廠,MPL等

爲什麼會出現警告以及如何糾正代碼,所以沒有警告產生的?

編輯:
要解決,下面添加實施HASH_VALUE


template<typename CharType, typename TraitsType> 
std::size_t hash_value(const ATL::CStringT<CharType, TraitsType>& s) 
{ 
    return CStringElementTraits<typename TraitsType>::Hash(s); 
} 
+0

我在我的代碼也有類似的警告一次。那裏發生了,當我試圖用一個const char *(或const wchar_t *在你的情況下)調用一個模板函數並且有多個重載可用時。我想隱式轉換爲字符串,但編譯器選擇了轉換爲bool。 – MP24 2009-10-08 14:17:57

+0

我想知道它是否有助於編譯GCC,我記得它很明確地說明問題來自哪裏?或者是MFC完全不可行?或者海灣合作委員會不給這個警告? – PJTraill 2016-06-17 12:37:15

回答

2

flyweight中的一個類可能使用hash_value函數(或包裝類哈希)來計算來自ATL :: CString的哈希值。這不是定義於boost直接,所以你需要提供一個實現:

std::size_t hash_value(const ATL::CString& s) 
{ 
    // ... 
} 

就看你的編譯器的輸出,似乎CString的本身是模板化,所以你會實現

template<typename CharType, typename TraitsType> 
std::size_t hash_value(const ATL::CString<CharType, TraitsType>& s) 
{ 
    // calculate hash e.g. by calling hash_value(const std::string&) 
} 
+0

中占主導地位。的確,hash_value是基於bool生成的。在這種情況下完全不正確。原始問題中提供的實現。 – 2009-10-10 05:40:35

3

我用/壁掛編譯導致加速產生各種警告的。此外,我指示編譯器將所有警告視爲錯誤,因此根本不需要警告。

爲了避免收到任何警告,而編譯Boost頭,我使用#pragma警告,暫時降低警戒水位儘可能低,並關閉任何剩餘的警告,在處理Boost頭:

 
// set minimal warning level 
#pragma warning(push,0) 
// some warnings still occur at this level 
// if necessary, disable specific warnings not covered by previous pragma 
#pragma warning(disable:4800) 

#include 

// restore warning level 
#pragma warning(pop) 

這可以確保我的代碼是用最高級別的錯誤檢查進行編譯的,而我無法控制的代碼仍然可以成功編譯。

我能看到的唯一的其他選項是忽略警告或維護Boost代碼的補丁版本,直到這些警告被修復爲止,這兩種方法都非常有吸引力。

+0

我真的不想禁用警告。無論如何感謝您的建議。 – 2009-10-08 11:26:37

0

我不知道該如何糾正警告,但您可以通過添加下面的代碼到你的CPP文件將其關閉:

#pragma warning(disable:4800) 

看看MSDN以備將來參考。

+0

不想禁用警告。這是脫離主題。 – 2009-10-08 11:27:17

0

警告的來源不在您的代碼中。您必須修復有問題的Boost代碼。

+0

沒有幫助。使用模板時,雖然它可以是編譯警告/錯誤的擴展代碼,但根本原因可以在應用程序代碼 – brewmanz 2015-10-12 23:38:38

3

C4800警告是由編譯器發出的,必須將int表達式轉換爲bool。

E.g. :

int k = 11; 
bool f() 
{ return k; } 

的int表達k被從

k == 0 => *false* 
k != 0 => *true* 

內部定義變換成的

b == false (internally == 0) => *false* 
b == true (internally == 1) => *true* 

布爾定義,因爲任何值(其他然後0)可在C++中代表true,編譯器必須將k轉換爲bool。

正如警告中正確地指出的那樣,這種轉換可能會帶來性能問題。

注意:此警告可能有點多餘,因爲編譯器通常會從代碼中提取正確的含義,並將其優化。

僞C代碼,編譯器會從我的示例代碼創建:

char f() 
{ 
    if(k) 
     return (char) 1; 
    return (char) 0; 
} 
+0

謝謝,我正在尋找關於C4800有多糟糕的解釋,但沒有找到任何地方! – Vargas 2011-12-06 14:00:56