在Boost ICL中,当我在间隔集上调用cardinality()或size()函数时,返回类型为size_t,与间隔类型无关。在32位机器上,这是一个32位无符号整数。但是,如果我的间隔是int64_t类型,则基数很容易溢出32位整数。我错过了一些明显的东西,或者这是这个库的严重缺陷吗?
编辑:添加了示例
以下代码在64位上编译并运行时没有错误,但在32位计算机上没有错误,它会抛出断言。
#include <boost/icl/interval_set.hpp>
int main()
{
boost::icl::interval_set<int64_t> is;
is.add(boost::icl::interval<int64_t>::closed(1, 4294967297LL));
assert(boost::icl::cardinality(is) == 4294967297LL);
}
编辑:我在Ubuntu 13.10上使用boost :: icl版本1.49.0
编辑:
这不是特别是32/64位的问题,因为以下代码无法在64位上运行
#include <boost/icl/interval_set.hpp>
int main()
{
boost::icl::interval_set<double> is;
is.add(boost::icl::interval<double>::closed(1, 1.5));
assert(boost::icl::cardinality(is) == 0.5);
}
答案 0 :(得分:2)
在Ubuntu 14.04.1 LTS上用Boost 1_54转载
这确实是一个错误。要修复的专业是
template <class Type>
struct get_size_type<Type, false, false, false>
{
typedef std::size_t type;
};
在icl/type_traits/size_type_of.hpp
。不知何故,ICL开发人员最近似乎没有使用-m32进行测试。
我已成功取代
// BEGIN SEHE WAS HERE
template <class Type>
struct get_size_type<Type, std::enable_if<not boost::is_arithmetic<Type>::value, mpl::false_>::type::value, false, false>
{
typedef std::size_t type;
};
template <class Type>
struct get_size_type<Type, std::enable_if<boost::is_arithmetic<Type>::value, mpl::false_>::type::value, false, false>
{
typedef typename std::common_type<Type, std::size_t>::type type;
};
// END SEHE WAS HERE
遗憾的是,这个特性并不是非常友好的SFINAE,因此使用SFINAE的第一个bool
模板参数进行了破解。改进可能是:
boost
类型特征common_type<...>
我已经对interval_set<double>
的DoTheRightThing(TM)以及g ++ -m32和-m64上的interval_set<uint64_t>
进行了测试。
我会在邮件列表上报告此内容。