簡體   English   中英

C ++ 14 constexpr靜態const std :: array初始化

[英]C++14 constexpr static const std::array initialization

這要長得多,但是現在我發現發生了什么事沒有幫助。

簡短的摘要:

  1. 變量int總和<64的模板。
  2. 我們想知道int的數量+最后一個int必須重復多少次才能達到總和> = 64。
  3. 我們想以constexpr const靜態數組std :: array結尾。

我在沒有類外部靜態成員聲明的情況下遇到了鏈接錯誤。 當存在時,Clang處於斷斷續續的狀態。

問題最終是我將功能定義為

<BitBranch, numberOfBranches> 

但是聲明最終使用了numberOfBranches訪問器方法

<BitBranch, branchCount()>

這是一個非常愚蠢的錯誤,但是對我而言,找到它並不明顯。

我將以我的代碼為例,以防有人覺得有用。

使用C ++ 14:

/* Using -std=c++1y */

#include <array>
#include <cmath>

template
<class          BitBranch,
 uint64_t...    BitLengths>
class BitBranchTree
{

計算Pack中的顯式參數覆蓋多少位

      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

您需要將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>{} );

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM