Как избавиться от предупреждения C4800, созданного при помощи boost :: flyweight в VS2008 - PullRequest
3 голосов
/ 08 октября 2009

Я получаю предупреждение при компиляции приведенного ниже кода в VS2008 с включенным MFC. Буст версия 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 \ functions \ hash \ extensions.hpp (72): предупреждение C4800: 'const wchar_t *': принудительное значение bool 'true' или 'false' (предупреждение о производительности)
d: \ work \ sourcecode \ boost1390 \ boost \ functions \ 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=ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t>>
]

Это предупреждение появляется и продолжается через фабрику хэширования, MPL и т. Д.

Почему там предупреждение и как мне исправить код, чтобы не выводилось предупреждение?

Edit:
Чтобы исправить, добавьте ниже реализацию hash_value


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

Ответы [ 5 ]

3 голосов
/ 08 октября 2009

Предупреждение C4800 генерируется компилятором, когда он должен преобразовать выражение int в логическое значение.

например. :

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

Выражение int k, преобразовано из внутреннего определения

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

до bool Определение

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

Поскольку любое значение (кроме 0) может представлять true в C ++, компилятор должен преобразовать k в логическое значение.

Как правильно сказано в предупреждении, это преобразование может привести к снижению производительности.

Примечание: это предупреждение может быть немного лишним, потому что компилятор обычно извлекает правильное значение из кода и оптимизирует его.

Псевдо-C-код, который компилятор создаст из моего примера кода:

char f()
{
    if( k )
       return (char) 1;
    return (char) 0;
}
3 голосов
/ 08 октября 2009

Я компилирую с / Wall, что заставляет Boost генерировать всевозможные предупреждения. Кроме того, я даю указание компилятору обрабатывать все предупреждения как ошибки, поэтому возникает необходимость вообще не предупреждать.

Чтобы не получать никаких предупреждений при компиляции заголовков 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, пока эти предупреждения не будут исправлены, ни один из которых не очень привлекательный.

2 голосов
/ 08 октября 2009

Один из классов в 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 голосов
/ 08 октября 2009

Источник предупреждения отсутствует в вашем коде. Вам придется исправить ошибочный код Boost.

0 голосов
/ 08 октября 2009

Я не знаю, как исправить это предупреждение, но вы можете отключить его, добавив приведенный ниже код в ваш файл cpp:

#pragma warning(disable:4800)

Взгляните на MSDN для дальнейшего ознакомления.

...