簡體   English   中英

C ++根據給定的類型名稱從Variant返回數據

[英]C++ Return data from a Variant according to the given typename

我有以下函數模板,根據給定的typenameVARIANT返回特定類型的數據。

template <typename T>
T VariantGetValue(VARIANT Variant) {

    std::string S(typeid(T).name());

    if (S == "wchar_t* __ptr64") { return Variant.bstrVal; }
    if (S == "unsigned int") { return Variant.uintVal; }
}

因此,當我需要從VARIANT返回一個unsigned int類型時,我嘗試使用上面的函數,例如:

return VariantGetValue<unsigned int>(CV);

但是,不幸的是,編譯器似乎在這里忽略if (S == "....)情況,並給我錯誤:

C2440-'返回':無法從'BSTR'轉換為'unsigned int'

但是,如果我刪除該行, if (S == "wchar_t* __ptr64") { return Variant.bstrVal; } if (S == "wchar_t* __ptr64") { return Variant.bstrVal; } ,編譯器只給了我下面的警告:

C4715-'VariantGetValue':並非所有控制路徑都返回值

我可以排除此錯誤並繼續嗎? 是安全的,還是有其他替代方法可以執行而沒有編譯器錯誤?

基於代碼將在運行時采用的分支,不能有多個返回類型。 您最好的選擇是使用明確的專業知識。

template < typename T >
T VariantGetValue(VARIANT) = delete;

template <>
unsigned int VariantGetValue<unsigned int>(VARIANT Variant)
{
    VARIANT var;
    InitVariantFromUInt32(unsigned int{}, &var);

    if (Variant.vt != var.vt)
        throw std::runtime_error("bad get");
    return Variant.uintVal;
}

template <>
BSTR VariantGetValue<BSTR>(VARIANT Variant)
{
    if (/* check that Variant stores wchar_t* __ptr64 */)
        throw std::runtime_error("bad get");
    return Variant.bstrVal;
}

順便說一下,這就是std::getstd::variant

#include <iostream>
#include <variant>

using Variant = std::variant<int,std::string>;

int main()
{
    Variant v(13);

    std::cout << std::get<int>(v) << '\n'; // 13
  //std::cout << std::get<std::string>(v) << '\n'; // std::bad_variant_access
}

我已經實現了一個完整的示例,也許可以澄清評論中提出的一些問題。

#include <iostream>
#include <stdlib.h>
#include <string.h>

// Implement a mock VARIANT, don't take this code too seriously

typedef unsigned int VARTYPE;
typedef char* BSTR;
enum { VT_UI4, VT_BSTR };

struct VARIANT
{
    VARIANT() : bstrVal(nullptr) {}
    VARTYPE vt;
    union {
        unsigned int uintVal;
        BSTR bstrVal;
    };
};

void InitVariantFromUInt32(unsigned int u, VARIANT * v)
{
    v->vt = VT_UI4;
    v->uintVal = u;
}

void InitVariantFromString(char const * s, VARIANT * v)
{
    v->vt = VT_BSTR;
    delete[] v->bstrVal;
    v->bstrVal = new char[strlen(s)];
    strcpy(v->bstrVal, s);
}

// VARIANT get value functions

template < typename T >
T VariantGetValue(VARIANT) = delete;

template <>
unsigned int VariantGetValue<unsigned int>(VARIANT Variant)
{
    if (Variant.vt != VT_UI4)
        throw std::runtime_error("bad get");
    return Variant.uintVal;
}

template <>
BSTR VariantGetValue<BSTR>(VARIANT Variant)
{
    if (Variant.vt != VT_BSTR)
        throw std::runtime_error("bad get");
    return Variant.bstrVal;
}

int main()
{
    VARIANT v;
    InitVariantFromUInt32(14, &v);

    std::cout << VariantGetValue<unsigned int>(v) << '\n';
    try {
        std::cout << VariantGetValue<BSTR>(v) << '\n';
    } catch (std::exception const& e) {
        std::cout << "Get failed!" << '\n';
    }

    VARIANT w;
    InitVariantFromString("Hello World!", &w);

    std::cout << VariantGetValue<BSTR>(w) << '\n';

  //std::cout << VariantGetValue<bool>(w) << '\n'; // error: call to deleted function 'VariantGetValue'
}

暫無
暫無

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

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