最近,我在C++的隐式转换方面遇到了一些麻烦,所以我想找一种方法来警告人们,如果有人试图将int32_t分配给uint64_t或其他什么的话。BOOST_STATIC_ASSERT会在这方面发挥神奇的作用,但我所使用的代码库非常大,并且依赖于大量的隐式转换,因此立即用断言打破一切是不现实的。
看起来警告对我来说是理想的,但是,我不能让它真正发出警告。像这样的事什么也做不了:
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_ >())发布于 2011-05-26 16:19:10
你用的是什么版本的助推器?这个注释可能是您自己的警告起作用的原因,但是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),你会很好。叉指
https://stackoverflow.com/questions/6128293
复制相似问题