[英]C++ Return data from a Variant according to the given typename
我有以下函數模板,根據給定的typename
從VARIANT
返回特定類型的數據。
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::get
對std::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.