我正准备使用 Variadic模板
来定义用户定义的文字template<...>
unsigned operator "" _binary();
unsigned thirteen = 1101_binary;
GCC 4.7.0还不支持operator ""
,但在此之前我可以用一个简单的函数来模拟它。
template<char C> int _bin();
template<> int _bin<'1'>() { return 1; }
template<> int _bin<'0'>() { return 0; }
template<char C, char D, char... ES>
int _bin() {
return _bin<C>() | _bin<D,ES...>() << 1; // <-- WRONG!
}
当然不太正确:
int val13 = _bin<'1','1','0','1'>(); // <-- gives 10
因为我的递归移动了最右边的'1',而不是最左边的那些。
这可能是我的小事,但我看不到它。
_bin<C>() | _bin<D,ES...>() << 1;
行吗? 更新:我无法以相反的方式折叠递归,但我发现了sizeof...
。工作,但不完美。还有另一种方式吗?
template<char C, char D, char... ES>
int _bin() {
return _bin<C>() << (sizeof...(ES)+1) | _bin<D,ES...>() ;
}
答案 0 :(得分:1)
一种可能性是使用累加器:
template <char C>
int _binchar();
template<>
int _binchar<'0'>() { return 0; }
template<>
int _binchar<'1'>() { return 1; }
template<char C>
int _bin(int acc=0) {
return (acc*2 + _binchar<C>());
}
template<char C, char D, char... ES>
int _bin(int acc=0) {
return _bin<D, ES...>(acc*2 + _binchar<C>());
}
答案 1 :(得分:1)
在递归的任何一步,你已经知道最左边数字的等级。
template<char C> int _bin();
template<> int _bin<'1'>() { return 1; }
template<> int _bin<'0'>() { return 0; }
template<char C, char D, char... ES>
int _bin() {
return _bin<C>() << (1 + sizeof...(ES)) | _bin<D,ES...>();
}
答案 2 :(得分:1)
参数包相对不灵活,通常不会直接在其中编写算法。可变参数函数模板适合转发,但在尝试操作之前,我会将其打包成更易于管理的tuple
。
使用简单的binary_string_value
元函数,其中1的位置首先出现,并且使用通用tuple_reverse
元函数,模式将是
template< char ... digit_pack >
constexpr unsigned long long _bin() {
typedef std::tuple< std::integral_constant< digit_pack - '0' > ... > digit_tuple;
return binary_string_value< typename tuple_reverse< digit_tuple >::type >::value;
}