[英]C++14 constexpr static const std::array initialization
這要長得多,但是現在我發現發生了什么事沒有幫助。
簡短的摘要:
我在沒有類外部靜態成員聲明的情況下遇到了鏈接錯誤。 當存在時,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.