2009-10-08 32 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