BOOST_STATIC_WARNING

Recientemente tuve algunos problemas con el casting implícito de C ++, así que estoy buscando una manera de advertir a las personas si alguien intenta asignar un int32_t a un uint64_t o lo que sea. @BOOST_STATIC_ASSERT funcionaría de maravilla para esto, excepto que la base de código con la que estoy trabajando es bastante grande y se basa en una gran cantidad de casting implícito, por lo que romper todo inmediatamente con afirmaciones no es realista.

Parece que BOOST_STATIC_WARNING sería ideal para mí, sin embargo, no puedo hacer que emita una advertencia. Algo como esto no hará nada:

    typedef boost::is_same<int64_t, int32_t> same_type;
    BOOST_STATIC_WARNING(same_type::value);

Mi compilador es g ++ 4.4.3 con --std = c ++ 0x -Wall -Wextra. Mi impulso es 1.46.1.

El problema que estoy tratando de resolver aquí es que tenemos un tipo de búfer que tiene métodos comouint8_t GetUInt8(size_type index), void SetUInt32(size_type index, uint32_t value), etc. Entonces, ves un uso como este:

x = buffer.GetUInt16(96);

El problema es que no hay garantía de que, mientras está leyendo un entero sin signo de 16 bits, quex es en realidad 16 bits. Mientras que la persona que originalmente escribió esa línea lo hizo correctamente (con suerte), si el tipo dex cambios, esta línea se romperá en silencio.

Mi solución es crear unsafe_convertable<T> escriba así:

template <typename T>
struct safe_convertable
{
public:
    template <typename TSource>
    safe_convertable(const TSource& val)
    {
        typedef boost::is_same<T, TSource> same_type;
        BOOST_STATIC_WARNING(same_type::value);

        _val = val;
    }

    template <typename TDestination>
    operator TDestination ()
    {
        typedef boost::is_same<T, TDestination> same_type;
        BOOST_STATIC_WARNING(same_type::value);

        return _val;
    }
private:
    T _val;
};

y cambie los métodos para devolver y aceptar estas referencias seguras:safe_reference<uint8_t> GetUInt8(size_type index), void SetUInt32(size_type index, safe_reference<uint32_t> value) (esa es la versión corta, hay otros operadores y todo lo que puede hacer con las referencias).

e todos modos, esto funciona muy bien conBOOST_STATIC_ASSERT, salvo por el hecho de que quiero advertencias y no errores.

Para los curiosos, he implementado la advertencia yo mismo, que funciona bien, pero preferiría la variedad Boost para que obtenga todas las otras características de Boost (esto solo funciona dentro de una función).

namespace detail
{
    template <typename TIntegralContant>
    inline void test_warning(const TIntegralContant&)
    {
        static_cast<void>(1 / TIntegralContant::value);
    }
}

#define MY_STATIC_WARNING(value_) \
    ::detail::test_warning(::boost::integral_constant<bool, value_ >())

Respuestas a la pregunta(1)

Su respuesta a la pregunta