【问题标题】:c++0x: Variadic Template techniquec++0x:可变参数模板技术
【发布时间】:2011-11-12 18:40:09
【问题描述】:

我正在为使用可变参数模板

定义用户定义的文字做准备
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&lt;C&gt;() | _bin&lt;D,ES...&gt;() &lt;&lt; 1;这行吗?
  • 或者我必须转发所有内容并在之后将所有内容都转过来(不好)?
  • 或者其他我看不到的方式?

更新:我无法以相反的方式折叠递归,但我发现了sizeof...。有效,但并不完美。还有其他方法吗?

template<char C, char D, char... ES>
int _bin() {
    return   _bin<C>() << (sizeof...(ES)+1) | _bin<D,ES...>() ;
}

【问题讨论】:

标签: recursion c++11 variadic-functions variadic-templates


【解决方案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】:

    参数包相对不灵活,通常不会直接在其中编写算法。可变参数函数模板非常适合转发,但在尝试操作之前,我会将其打包成更易于管理的 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;
    }
    

    【讨论】:

      【解决方案3】:

      一种可能性是使用累加器:

      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-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-13
      • 2022-01-23
      相关资源
      最近更新 更多