簡體   English   中英

如何在運行時根據循環元素類型確定 std::vector 類型?

[英]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.

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