3

在打开 MFC 的 VS2008 中编译以下代码时,我收到警告。提升版本 1.39


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:\work\sourcecode\boost1390\boost\functional\hash\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:\work\sourcecode\boost1390\boost\multi_index\hashedindex.hpp(1159) 编译类模板成员函数时:参见类模板实例化的参考 'boost ::hash<T>' 使用
[
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);
}
4

5 回答 5

3

我使用 /Wall 进行编译,这会导致 Boost 生成各种警告。此外,我指示编译器将所有警告都视为错误,因此根本不需要警告。

为了避免在编译 Boost 标头时收到任何警告,我使用 #pragma warning 将警告级别暂时降低到尽可能低,并在处理 Boost 标头时关闭任何剩余的警告:

// 设置最小警告级别
#pragma 警告(推,0)
// 在这个级别仍然会出现一些警告
// 如有必要,禁用先前 pragma 未涵盖的特定警告
#pragma 警告(禁用:4800)

#包括

// 恢复警告级别
#pragma 警告(弹出)

这确保我的代码编译时使用了最高级别的错误检查,而我无法控制的代码仍然可以成功编译。

我能看到的唯一其他选择是忽略警告或维护 Boost 代码的修补版本,直到这些警告得到修复,这两者都不是很吸引人。

于 2009-10-08T11:21:44.823 回答
3

当编译器必须将 int 表达式转换为 bool 时,会发出 C4800 警告。

例如:

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;
}
于 2009-10-08T16:58:18.373 回答
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&)
}
于 2009-10-08T14:05:35.897 回答
0

我不知道如何纠正该警告,但您可以通过将以下代码添加到您的 cpp 文件来关闭它:

#pragma warning(disable:4800)

查看MSDN以获取更多参考。

于 2009-10-08T11:23:29.593 回答
0

警告的来源不在您的代码中。您必须修复有问题的 Boost 代码。

于 2009-10-08T11:30:26.553 回答