[英]How to decide a std::vector Type in runtime depends on loop elements type?
我有自己的數據類型列表,我想將其轉換為原始類型的 std::vector (int8_t/int/...)。
我想創建一個原始類型 (int32/int8) 的向量,它將在運行時根據我的元素類型進行選擇。 (我的列表不能容納不同類型的元素)
我有這個循環:
std::vector<void*> createPrimitiveList(MyClass list_data) {
std::vector<void*> listPrimitive;
for (size_t index = 0; index < list_data.Size(); ++index) {
switch(list_data[index].type) {
case MyClass::TYPES::INT32:
listPrimitive.push_back(list_data[index].val);
case MyClass::TYPES::UINT8:
listPrimitive.push_back(list_data[index].val);
}
}
return listPrimitive;
}
但我不想創建 void* 類型的向量,我想要實際的原始類型。 如果數據類型為 int8/char/... 我不想使用 sizeof(void*) 字節)我嘗試使用“使用”鍵來獲取類型,但使用聲明需要合格的
可以用c ++完成嗎?
我不確定我是否正確理解了所有內容。
您在標簽中提到了策略模式。 但我猜你應該使用一種創建模式,比如工廠或其他什么。
但是由於您的類MyClass
中已經有一個類型,例如MyClass::TYPES::INT32
您已經知道函數的返回類型。
此外, type_traits庫中還有許多可用的類型特征函數。 您幾乎總能找到滿足您需求的東西。
反正。 我想向您展示一個基於模板的功能。 這讓生活變得更簡單。 重要的是,我們可以使用type_trait
來檢測您類的基礎數據的類型。
我們使用std::tuple
作為類型列表。 還有一些數字選擇器。
然后我們可以使用std::tuple_element_t自動獲取並選擇所需的類型。 我們將using
語句作為別名。 例如與
using Type = std::tuple_element_t<INT64, MyTypes>;
然后,模板函數將簡單地創建具有已知類型的std::vector
。 現在很容易。
主要是,我們將使用類模板參數推導 (CTAD)優雅地定義具有所需類型的std::vector
並使用我們的函數分配值。
這可能看起來像這樣:
#include <iostream>
#include <array>
#include <vector>
#include <deque>
#include <list>
#include <cstdint>
#include <tuple>
// Type list and selector
using MyTypes = std::tuple <int8_t, int16_t, int32_t, int64_t>;
constexpr int INT8{ 0 }, INT16{ 1 }, INT32{ 2 }, INT64{ 3 };
// Some demo classes
struct MyClassArray {
using Type = std::tuple_element_t<INT8, MyTypes>;
std::array<Type, 10> value{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
};
struct MyClassVector {
using Type = std::tuple_element_t<INT16, MyTypes>;
std::vector<Type> value{ 11,12,13,14,15,16,17,18,19,20 };
};
struct MyClassDeque {
using Type = std::tuple_element_t<INT32, MyTypes>;
std::deque<Type> value{ 31,32,33,34,35,36,37,38,39,30 };
};
struct MyClassList {
using Type = std::tuple_element_t<INT64, MyTypes>;
std::list<Type> value{ 41,42,43,44,45,46,47,48,49,40 };
};
// Create a vector with appropriate type
template <typename T>
auto createPrimitiveList(T& data) -> std::vector<typename T::Type> {
return { data.value.begin(), data.value.end() };
}
int main() {
// Define some classes
MyClassArray mca{};
MyClassVector mcv{};
MyClassDeque mcd{};
MyClassList mcl{};
// Get vector with type dependent on input class
// Use Class Template Argument Deduction (CTAD)
std::vector i8 = createPrimitiveList(mca);
std::vector i16 = createPrimitiveList(mcv);
std::vector i32 = createPrimitiveList(mcd);
std::vector i64 = createPrimitiveList(mcl);
// Some debug output
for (const auto i : i8) std::cout << (int)i << ' '; std::cout << '\n';
for (const auto i : i16) std::cout << (int)i << ' '; std::cout << '\n';
for (const auto i : i32) std::cout << (int)i << ' '; std::cout << '\n';
for (const auto i : i64) std::cout << (int)i << ' '; std::cout << '\n';
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.