[英]Compile time size of data member std::array in non-class template (C++14)
我需要靜態斷言非模板類的std::array
類型的非 constexpr 數據成員的編譯時大小,比如arr_
,等於給定的(外部提供的)常量。 靜態斷言將從類內部完成,這意味着arr_
是可訪問的,但我不能依賴任何存儲的常量(也不是非類型模板參數)的大小。 即,斷言需要僅依賴於arr_
數據成員的“一些檢查”。
如果constexpr
std::array<>::size()
/ std::array<>::max_size()
是靜態成員函數( decltype(arr_)::size()
/ decltype(arr_)::max_size()
我基本上會完成decltype(arr_)::max_size()
) 而不是非靜態成員函數。
我有一種在arr_
成員的指向數據成員的指針上使用函數模板參數推導的工作方法,但我想知道是否有更簡單/更整潔的方法。
#include <array>
#include <cstddef>
// Defined/provided from elsewhere.
constexpr std::size_t kArraySize = 12U;
constexpr std::size_t kAnotherArraySize = 12U;
template <typename T, typename U, std::size_t N>
constexpr std::size_t size_of_data_member_array(std::array<T, N> U::*) {
return N;
}
class Foo {
std::array<int, kArraySize> arr_;
static_assert(size_of_data_member_array(&Foo::arr_) == kAnotherArraySize, "");
};
int main() {}
該標准在名稱tuple_size
下提供了array::size
的靜態版本:
#include <array>
#include <tuple> // for std::tuple_size_v
static_assert(std::tuple_size<decltype(arr_)>::value == kAnotherArraySize, "");
static_assert(std::tuple_size_v<decltype(arr_)> == kAnotherArraySize); // C++17
您可以在靜態斷言中創建一個具有相同類型Foo::arr_
的數組實例:
class Foo {
std::array<int, kArraySize> arr_;
static_assert(decltype(arr_){}.size() == kAnotherArraySize, "");
};
請參閱此示例。
注意:這僅在數組值類型是 POD 或具有默認 constexpr 構造函數時才有效。
只是為了提供另一種選擇,您可以對模板變量進行部分專業化。
#include <array>
#include <cstddef>
// Defined/provided from elsewhere.
constexpr std::size_t kArraySize = 12U;
constexpr std::size_t kAnotherArraySize = 12U;
template <typename T>
constexpr std::size_t array_size = 0;
template <typename T, std::size_t N>
constexpr std::size_t array_size<std::array<T, N>> = N;
class Foo {
std::array<int, kArraySize> arr_;
static_assert(array_size<decltype(arr_)> == kAnotherArraySize, "");
};
int main() {}
使用 SFINAE 提供另一種選擇:
#include <type_traits>
#include <array>
template <typename T>
constexpr bool is_array_v = false;
template <typename T, size_t N>
constexpr bool is_array_v<std::array<T, N>> = true;
template <typename Array, std::enable_if_t<is_array_v<Array>, int> = 0>
constexpr size_t array_size_v = std::tuple_size<Array>::value;
static_assert(array_size_v<std::array<int, 5>> == 5); // OK
static_assert(array_size_v<int> == 5); // Won't compile
與其他提議不同,這將在編譯時發現對array_size_v
誤用,因此輸入int
和其他不是std::array
類型將不起作用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.