[英]std::array vs C-Style array for contiguous memory
這只是出於興趣的實驗...
我試圖使一個容器在一個連續的內存塊中容納固定數量的字節(例如標頭)和動態數據塊(例如主體)。 在傳統的C編程中,我將char[0]
作為最后一個實例變量,並且我將過度分配sizeof(struct) + data_length
。
這在C ++中有效,但是我想要更好的東西。 所以我的問題是std::array
以指針開頭,或者可以與本機C樣式數組相同的方式使用?
這是一些示例代碼...
struct pkg_base
{
virtual std::size_t get_body_size() = 0;
virtual void *get_body_ptr() = 0;
};
template<typename _T, std::size_t _N>
struct pkg
: public pkg_base
{
std::uint16_t a;
std::uint16_t b;
std::uint16_t c;
std::array<_T, _N> body{};
std::size_t get_body_size() override
{
return ( body.size() );
}
virtual void *get_body_ptr() override
{
return ( body.data() );
}
};
void _test_package()
{
auto vec = std::vector<std::unique_ptr<pkg_base>>{};
vec.push_back(std::make_unique<pkg<char, 1024>>());
vec.push_back(std::make_unique<pkg<float, 1024>>());
vec.push_back( std::make_unique<pkg<std::string, 1024>>() );
auto const size = vec.front()->get_body_size();
auto const *ptr = static_cast<char *>( vec.front()->get_body_ptr() );
}
所以我的問題是std :: array是否以指針開頭,或者可以與本機C樣式數組相同的方式使用?
從文檔中
此容器是一種聚合類型,其語義與將C型數組T [N]作為其唯一的非靜態數據成員的結構具有相同的語義。
因此,那里沒有其他數據成員,只有您想要的T[N]
數組。
您可以使用sizeof
或查看代碼來自己確認一下。
_N
,以_[AZ]
開頭的名稱是為實現保留的,因此您可能不應該調用模板類型參數_T
和_N
。
一個std::array
在其他地方不包含任何指向數據的指針,一個std::array
直接在內部保存數據,其中沒有動態的東西。
它被設計為提供類似於標准數組的語義,但具有標准STL容器的某些特征。
這是一個聚合類,主要實現為
namespace std
{
template<typename T, size_t S>
class array
{
T __elems_[S];
}
}
您有array.data()
已經返回一個C數組,所以我沒有得到您的要求。
作為參考,您所引用的技術稱為“ flexible array member
,但是不幸的是,C ++不支持將其用作核心功能或標准庫功能。 我覺得這很令人失望。
std::array
是一個經過修飾的C樣式數組(某些成員允許將其用作STL容器,例如迭代,調整大小,類型自省等)。
我知道實現與靈活數組成員相似的功能的唯一方法是創建一個std::vector<char>
,其大小設置為sizeof(header) + <extra bytes for payload>
,然后placement new
vector.data()
中的placement new
標頭。 您可以將所有這些包裝在幫助器類中,以節省一些在多種情況下可以輸入的內容。
我可以建議將類型擦除作為您問題的一般解決方案。 在現代C ++中,除非不可避免,否則有遠離原始指針直接操作的趨勢:
struct common_part{
//declare common data and ctor
protected:
virtual elem* end(){return begin()+size();};
virtual elem *begin()=0 ;
virtual ~common_part()=default;
virtual std::size_t size()=0;
};
template<std::size_t N>
struct instance_type:
common_part{
protected:
void elem* begin() override{return arr;};
void elem* end() override{return arr+N;};
void std::size_t size() override{return N;};
private:
elem arr[N];
};
std::unique_ptr<common_part> ptr {new instance_type<N>{}};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.