簡體   English   中英

我可以使用可變參數模板函數返回不同的類型嗎?

[英]Can I have variadic template function returning different types?

我正在從字節數組中進行反序列化,並制作了ExtractData可變參數模板,因此它的工作方式類似於

QByteArray data; // (this works just like std::vector<char>)
std::vector<std::any> values = ExtractData<float, char>(data); // read a float, char sequentially from data
float readFloat = std::any_cast<float>(values[0]);
float readChar = std::any_cast<char>(values[1]);

但仍然有很多樣板可用於解碼內容。
理想情況下,我想要類似

float readFloat;
char readChar;
std::tie(readFloat, readChar) = ExtractData<float, char>(data);

ExtractData結構基本上是

using anyVec = std::vector<std::any>;

// one type resolution
template<typename T>
anyVec ExtractData(const QByteArray& data, anyVec out = {}){
    // extract T value, assign to std::any, push_back into out
    return outVec;
}

// multiple types resolution
template<typename T, typename... Rest>
typename std::enable_if<(sizeof...(Rest) > 0), anyVec>::type
ExtractData(const QByteArray& data, anyVec out = {}){
    // extract T value, assign to std::any, push_back into out
    return ExtractData<Rest...>(data, out);
}

我只是看不到如何使ExtractData<type1, type2, ...>(data)返回std::tuple<type1, type2, ...>因為當模板類型列表丟失時,所有原始類型信息都會丟失“開卷”。 可能嗎? 抱歉,如果我缺少明顯的內容,我對c ++ 11和更高版本還是很陌生。

我看到我可以為固定數量的類型制作模板,但這可悲的不是我的用例。


我正在使用Qt 5.11,c ++ 14(此處省略了命名空間中的experimental ),但也很高興聽到c ++ 17的建議。 我正在使用的確切代碼段: https : //gist.github.com/tjakubo2/dc3e6897bf42f3bed78933031e53786b

遵循這些思路,也許是:

template <typename T>
T ExtractOnePiece(const QByteArray& data, int& offset);

template <typename... Ts>
std::tuple<Ts...> ExtractData(const QByteArray& data) {
    int offset = 0;
    return {ExtractOnePiece<Ts>(data, offset)...};
}

演示 您想要支持的每種ExtractOnePiece的每種類型的ExtractOnePiece專業ExtractOnePiece都保留下來。

多虧了#include Discord服務器的Ben和Seph的幫助,就像Igor在此處的回復中所建議的那樣,我找到了:

template<typename T>
std::tuple<T> ExtractSingle(const QByteArray& data, size_t offset){
    // pull T_val from data at given offset
    return std::tuple<T>{T_val};
}

template<typename T>
std::tuple<T> ExtractData(const QByteArray& data, size_t offset = 0){
    return ExtractSingle<T>(data, offset);
}

template<typename T, typename... Rest>
typename std::enable_if<(sizeof...(Rest) > 0), std::tuple<T, Rest...>>::type
ExtractData(const QByteArray& data, size_t offset = 0){
    auto val = ExtractSingle<T>(data, offset);
    return std::tuple_cat(std::move(val), ExtractData<Rest...>(data, offset + sizeof(T)));
}

正是我想要的。 我想它可以提高性能,但是到目前為止我的應用程序並不需要這樣做。 干杯!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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