【发布时间】:2013-04-26 16:54:06
【问题描述】:
在数学中有不同类型的范围:它们可以是打开的( (a, b) )、关闭的( [a, b] )、左打开的(a, b] )或右打开的( [a, b) )。
我想用 C++(不是 11)编写一个模板函数,可以轻松管理这些情况。但我对元编程和模板不太有信心。
我想要这样的东西:
const int max = MAX, int min = MIN;
int x = value;
// check close range
if ( is_in_range( x, min, max ) ) //...
if ( is_in_range( x, min, max, open) ) //...
if ( is_in_range( x, min, max, left_open) ) //...
if ( is_in_range( x, min, max, right_open) ) //...
有人有什么建议吗?
编辑 1
我试过了,但无法编译
enum { range_open, range_close, range_left_open, range_right_open };
namespace detail {
template < typename Type >
inline bool check_open_range( const Type& x, const Type& max, const Type& min )
{
return ( min < x ) && ( x < max );
}
template < typename Type >
inline bool check_close_range( const Type& x, const Type& max, const Type& min )
{
return ( min <= x ) && ( x <= max );
}
template < typename Type >
inline bool check_left_open_range( const Type& x, const Type& max, const Type& min )
{
return ( min < x ) && ( x <= max );
}
template < typename Type >
inline bool check_right_open_range( const Type& x, const Type& max, const Type& min )
{
return ( min <= x ) && ( x < max );
}
}
template < typename Type, int range_open >
inline bool check_range( const Type& x, const Type& max, const Type& min );
template < typename Type, range_open >
inline bool check_range( const Type& x, const Type& max, const Type& min )
{
return detail::check_open_range( x, min, max );
}
template < typename Type, range_close >
inline bool check_range( const Type& x, const Type& max, const Type& min )
{
return detail::check_close_range( x, min, max );
}
template < typename Type, check_left_open_range >
inline bool check_range( const Type& x, const Type& max, const Type& min )
{
return detail::check_left_open_range( x, min, max );
}
template < typename Type, check_right_open_range >
inline bool check_range( const Type& x, const Type& max, const Type& min )
{
return detail::check_right_open_range( x, min, max );
}
但实际上使用 4 个重载函数更简单
编辑 2
namespace detail {
template < typename Type >
inline bool check_open_range( const Type& x, const Type& max, const Type& min )
{
return ( min < x ) && ( x < max );
}
template < typename Type >
inline bool check_close_range( const Type& x, const Type& max, const Type& min )
{
return ( min <= x ) && ( x <= max );
}
template < typename Type >
inline bool check_left_open_range( const Type& x, const Type& max, const Type& min )
{
return ( min < x ) && ( x <= max );
}
template < typename Type >
inline bool check_right_open_range( const Type& x, const Type& max, const Type& min )
{
return ( min <= x ) && ( x < max );
}
}
struct range_open {};
struct range_close {};
struct left_open_range {};
struct right_open_range {};
template < typename Type >
inline bool check_range( const Type& x, const Type& max, const Type& min)
{
return detail::check_open_range( x, min, max );
}
template < typename Type >
inline bool check_range( const Type& x, const Type& max, const Type& min, const range_open&)
{
return detail::check_open_range( x, min, max );
}
template < typename Type >
inline bool check_range( const Type& x, const Type& max, const Type& min, const range_close& )
{
return detail::check_close_range( x, min, max );
}
template < typename Type >
inline bool check_range( const Type& x, const Type& max, const Type& min, const left_open_range& )
{
return detail::check_left_open_range( x, min, max );
}
template < typename Type >
inline bool check_range( const Type& x, const Type& max, const Type& min, const right_open_range& )
{
return detail::check_right_open_range( x, min, max );
}
我觉得Edit 2是对的……
编辑3:好版本
结构 left_open { 模板 static bool compare (const T& value, const T& range) { return range
struct left_close {
template <class T>
static bool compare (const T& value, const T& range) { return range <= value; }
};
struct right_open {
template <class T>
static bool compare (const T& value, const T& range) { return value < range; }
};
struct right_close {
template <class T>
static bool compare (const T& value, const T& range) { return value <= range; }
};
template <class L, class R, class T>
bool check_range(const T& value, const T& min, const T& max)
{
return L::compare <T> (value, min) && R::compare <T> (value, max);
}
【问题讨论】:
-
你需要元编程吗?
-
看起来您想在运行时确定范围的“开放性”(关闭/打开/left_open/right_open)。这是故意的吗,还是您在编写代码时也可以决定?
-
在模板元编程中,
<>通常用于代替()(然后必须手动检索结果值) -
STL 中是否有可用的东西来检查范围?