我正在尝试编写一个类方法,该方法可以根据DataType结构变量中保存的值返回任何一个成员变量值。我已经尝试过以下代码:
#include <iostream>
struct A
{
int DataType;/* holds enum value for one of below data data needs to be returned */
union /* value of var is one of these needs to be returned */
{
int32_t x;
uint32_t y;
uint64_t mz;
bool b;
struct
{
char* ptr;
int len;
} str;
}data;
};
struct A a1 = { /* value 1 means int32_t, 2 means uint32_t, 3 means uint64_t , 4 means bool and 5 means str */ 2, 32};
//struct A a2 = { /* value 1 means int32_t, 2 means uint32_t, 3 means uint64_t , 4 means bool and 5 means str */ 5, {{ "Hello",5}}};
class B
{
public:
B(){}
template <>
T GetVar(struct A a0)
{
if (a0.DataType == 2)
return a0.data.y;
if (a0.DataType == 5)
return std::string(a0.data.str.ptr);
return 0;
}
};
int main()
{
B b1;
auto d = b1.GetVar(a1);
std::cout << d << std::endl;
//auto d1 = b1.GetVar(a2);
std::cout << d << std::endl;
}
我遇到编译错误-而且我知道该错误与初始化 struct A 的 str 成员变量(如何解决此问题)以及类如何相关方法返回不同的变量值?
$ c++ -std=c++11 try72.cpp
try72.cpp:26:11: error: explicit specialization in non-namespace scope 'class B'
template <>
^
try72.cpp:27:1: error: 'T' does not name a type
T GetVar(struct A a0)
^
try72.cpp: In function 'int main()':
try72.cpp:40:13: error: 'class B' has no member named 'GetVar'
auto d = b1.GetVar(a1);
^
try72.cpp:42:14: error: 'class B' has no member named 'GetVar'
auto d1 = b1.GetVar(a2);
^
try72.cpp:42:21: error: 'a2' was not declared in this scope
auto d1 = b1.GetVar(a2);
^
答案 0 :(得分:0)
一个函数具有一个返回类型。您需要不同的函数来返回不同类型的值。
(在C ++ 17中,您可以使其看起来像从函数返回不同的类型,但这实际上是针对各种值实例化的模板)
如果您要根据所包含的并集类型选择要执行的操作,则可以改用std::variant
的灵感,并接受带有多个operator()
的函数对象,每种可能一个类型。
template <typename Return>
struct AVisitor
{
virtual Return operator()(int32_t) const = 0;
virtual Return operator()(uint32_t) const = 0;
virtual Return operator()(uint64_t) const = 0;
virtual Return operator()(bool) const = 0;
virtual Return operator()(std::string) const = 0;
};
template <typename Return>
Return visit(const A & a, const AVisitor<Return> & visitor)
{
switch (a.DataType)
{
case 1: return visitor(a.data.x);
case 2: return visitor(a.data.y);
case 3: return visitor(a.data.mz);
case 4: return visitor(a.data.b);
case 5: return visitor(std::string(a.data.str.ptr));
}
}
struct cout_visitor : AVisitor<void>
{
void operator()(int32_t x) const { std::cout << x; }
void operator()(uint32_t y) const { std::cout << y; }
void operator()(uint64_t mz) const { std::cout << mz; }
void operator()(bool b) const { std::cout << b; }
void operator()(std::string str) const { std::cout << str; }
}
int main()
{
cout_visitor vis;
visit(a1, vis);
visit(a2, vis);
}
尽管显而易见的替代方案是将A
定义为using A =
(std::
或boost::
)variant<int32_t, uint32_t, uint64_t, bool, std::string>;