Doh! Так много для этой идеи. Не возражаете, регистрируя ошибку?

я недавно были некоторые проблемы с неявным приведением C ++, поэтому я ищу способ предупредить людей, если кто-то пытается присвоить int32_t для uint64_t или чего-то еще.BOOST_STATIC_ASSERT это могло бы творить чудеса, за исключением того, что кодовая база, с которой я работаю, достаточно велика и опирается на множество неявных приведений, поэтому немедленное нарушение всего с помощью утверждений нереально.

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

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

Мой компилятор g ++ 4.4.3 с --std = c ++ 0x -Wall -Wextra. Мой буст 1.46.1.

Проблема, которую я пытаюсь решить, состоит в том, что у нас есть тип буфера, который имеет такие методы, какuint8_t GetUInt8(size_type index), void SetUInt32(size_type index, uint32_t value)и т. д. Итак, вы видите использование следующим образом:

x = buffer.GetUInt16(96);

Проблема в том, что нет гарантии, что, пока вы читаете 16-разрядное целое число без знака, чтоx на самом деле 16-битный. В то время как человек, который первоначально написал эту строку, сделал это правильно (надеюсь), если типx изменения, эта линия будет молча обрываться.

Мое решение состоит в том, чтобы создатьsafe_convertable<T> типа так:

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;
};

и измените методы для возврата и принятия этих безопасных ссылок:safe_reference<uint8_t> GetUInt8(size_type index), void SetUInt32(size_type index, safe_reference<uint32_t> value) (это короткая версия, есть другие операторы и все, что вы можете сделать со ссылками).

Во всяком случае, это прекрасно работает сBOOST_STATIC_ASSERTЗа исключением того факта, что я хочу предупреждения, а не ошибки.

Для любопытных я сам реализовал функцию предупреждения, которая отлично работает, но я бы предпочел вариант Boost, чтобы получить все остальные функции Boost (это работает только внутри функции).

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_ >())

Ответы на вопрос(1)

Ваш ответ на вопрос