C ++ 14 constexpr static const std :: array initialization

时间:2014-09-10 06:37:18

标签: c++ static initialization c++14 constexpr

这个时间要长得多,但现在我发现发生的事情没有用。

简短摘要:

  1. 具有可变整数的模板求和< 64。
  2. 我们想要知道整数的数量+最后一个int必须重复多少次才能达到总和> = 64。
  3. 我们希望最终得到一个constexpr const静态数组std :: array。
  4. 我没有在类之外声明静态成员而链接错误。在场的时候,Clang是分段的。

    问题最终是我将函数定义为

    <BitBranch, numberOfBranches> 
    

    但是声明最终使用了numberOfBranches访问器方法

    <BitBranch, branchCount()>
    

    一个非常愚蠢的错误,但追踪我并不是很明显。

    我会将我的代码作为示例,以防有人发现它有用。

    使用C ++ 14:

    /* Using -std=c++1y */
    
    #include <array>
    #include <cmath>
    
    template
    <class          BitBranch,
     uint64_t...    BitLengths>
    class BitBranchTree
    {
    

    计算包装中显式参数涵盖的位数

          template <typename ...Ints>
          constexpr static uint64_t countExplicitBits(
            uint64_t   bit_length,
            Ints...    bit_lengths ) 
          {
            return bit_length + countExplicitBits( bit_lengths... );
          }
    
          constexpr static uint64_t countExplicitBits( 
            uint64_t   bit_length ) 
          {
            return bit_length;
          }
    

    计算有多少位需要额外的隐式参数

          constexpr
          static
    
          uint64_t
    
          calculateImplicitBranches()
          {
            uint64_t remaining_bits            = 64 - explicitBitCount;
            uint64_t final_explicit_bit_length = explicitBranchLengths[ explicitBranchCount - 1 ];
            uint64_t smaller_final_length      = remaining_bits % final_explicit_bit_length;
            uint64_t remaining_full_branches   = remaining_bits / final_explicit_bit_length;
            uint64_t implicit_branch_count     = smaller_final_length ? remaining_full_branches + 1
                                                                      : remaining_full_branches;
    
            return implicit_branch_count;
          }
    

    初始化所需的最终数组

          template <uint64_t... Indexes>
          constexpr static std::array<BitBranch, sizeof...(Indexes)>
          initializeBranches(
            std::integer_sequence<uint64_t, Indexes...> )
          {
            return { initializeBranch( Indexes )... };
          }
    

    初始化最终数组的每个分支

          constexpr static BitBranch
          initializeBranch(
            uint64_t index )
          {
            uint64_t bit_length = ( index < explicitBranchCount )
                                  ? explicitBranchLengths[ index ]
                                  : explicitBranchLengths[ explicitBranchCount - 1 ];
    
            return BitBranch( bit_length );
          }
    

    会员变量/初始化

          constexpr static const uint64_t
          explicitBranchCount = sizeof...(BitLengths);
    
          constexpr static const uint64_t
          explicitBitCount = countExplicitBits( BitLengths... );
    
          constexpr static const uint64_t
          explicitBranchLengths[ explicitBranchCount ] = { BitLengths... };
    
          constexpr static const uint64_t
          implicitBranchCount = calculateImplicitBranches();
    
          static const uint64_t
          numberOfBranches = explicitBranchCount + implicitBranchCount;
    
          constexpr static const std::array <BitBranch, numberOfBranches>
          branches = initializeBranches( std::make_integer_sequence <uint64_t, numberOfBranches>{} );
    };
    

    最后,在课堂之外

        template
        <class          BitBranch,
         uint64_t...    BitLengths>
    
        constexpr
        const
        std::array
              <BitBranch,
               BitBranchTree<BitBranch, BitLengths...>::numberOfBranches>
    
        BitBranchTree<BitBranch, BitLengths...>::branches;
    

    用法示例

    typedef
    BitBranchTree<BitBranchMock, 4, 16, 7, 8, 5, 2, 8, 12, 2>
    CompleteSpecification; // Results in Branches: 4, 16, 7, 8, 5, 2, 8, 12, 2
    
    typedef
    BitBranchTree<BitBranchMock, 4, 16>
    PartialSpecification;  // Results in Branches: 4, 16, 16, 16, 12
    

1 个答案:

答案 0 :(得分:2)

您需要将BitBranchTree::branches的定义与以下声明匹配

template
<class          BitBranch,
 uint64_t...    BitLengths>
constexpr const std::array <BitBranch, BitBranchTree<BitBranch, BitLengths...>::numberOfBranches>
BitBranchTree<BitBranch, BitLengths...>::branches;

您也可以更改声明以使用branchCount(),重要的是它们是相同的。

由于编译器错误,推测clang 3.4崩溃而不是出错,你的原始代码在clang 3.5上给出了以下错误

test.cpp:199:42: error: redefinition of 'branches' with a different type: 'array<[...], BitBranchTree<BitBranch, BitLengths...>::branchCount()>' vs
      'const array<[...], numberOfBranches>'
BitBranchTree<BitBranch, BitLengths...>::branches;
                                         ^
test.cpp:181:7: note: previous definition is here
      branches = initializeBranches( std::make_integer_sequence <uint64_t, numberOfBranches>{} );