簡體   English   中英

非類模板中數據成員 std::array 的編譯時間大小 (C++14)

[英]Compile time size of data member std::array in non-class template (C++14)

編譯時檢查 std::array 數據成員的(編譯時)大小

我需要靜態斷言非模板類的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.

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