1

Variadic Templateを使用してユーザー定義リテラルを定義する準備をしています

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' ではなく、一番右の '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...>() ;
}
4

3 に答える 3

1

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>());
}
于 2011-09-08T08:23:03.677 に答える
1

パラメーター パックは比較的柔軟性がなく、通常は直接アルゴリズムを記述しません。可変個引数関数テンプレートは転送に適していますが、それtupleを操作する前に、より扱いやすいものにまとめます。

binary_string_value1 の位が最初に来る単純なメタ関数と一般的なメタ関数を使用する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;
}
于 2011-09-08T08:36:12.690 に答える
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...>();
}
于 2011-09-08T08:33:00.320 に答える