BOOST_STATIC_WARNING

BOOST_STATIC_WARNING

本文关键字:WARNING STATIC BOOST      更新时间:2023-10-16

我最近在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_ >())

您使用的Boost版本是什么?这个评论可能是你自己的警告有效的原因,但增强版本不起作用:

// 6. replaced implementation with one which depends solely on
//    mpl::print<>.  The previous one was found to fail for functions
//    under recent versions of gcc and intel compilers - Robert Ramey

我猜,如果你升级到Boost的最新版本(例如1.46.1),你会很乐意去的交叉手指