我有一个带有私人联盟的班级Foo
:
class Foo
{
public:
static Foo foo(int type);
static Foo foo(double type);
static Foo foo(bool type);
static Bar getBar(Foo foo);
private:
union Bar
{
int iBar;
double rBar;
bool bBar;
} bar;
};
我可以写一个返回相应Bar的通用getter吗?
我试过了:
Bar Foo::getBar(Foo foo)
{
return foo.bar;
}
和其他变体但编译器没有识别名为" Bar"在" Foo"。
答案 0 :(得分:2)
两件事 - 与数据和函数成员不同,成员类型需要在使用之前声明,并且您需要在类外定义中完全限定嵌套类型:
class Foo {
// here, compiler doesn't yet know what Bar is
union Bar {
int iBar;
double rBar;
bool bBar;
} bar; // now it does
public:
static Bar getBar(Foo); // so use it
};
Foo::Bar Foo::getBar(Foo foo) { return foo.bar; }
// ^^^^^
如果它有任何实际用途,您可能还想Bar
public
。希望有所帮助。
答案 1 :(得分:0)
使用tuple。
示例:
// tuple's get
#include <iostream>
#include <tuple>
int main ()
{
std::tuple<int,char> mytuple (10,'a');
std::get<0>(mytuple) = 20;
std::cout << "mytuple contains: ";
std::cout << std::get<0>(mytuple) << " and " << std::get<1>(mytuple);
std::cout << std::endl;
return 0;
}
请注意,如果您有两个元素,则可以使用std::pair。
在更新的问题中,您需要转发声明联合Bar
,如下所示:
class Foo {
union Bar;
public:
static Foo foo(int type);
static Foo foo(double type);
static Foo foo(bool type);
static Bar getBar(Foo foo);
private:
union Bar {
int iBar;
double rBar;
bool bBar;
} bar;
};
此外,您所做的事情是不可接受的,因为bar
是Foo
的私人成员。
请注意,元组和联合并不完全相同。 “元组是一个包含多个值的数据类型。一个联合可以一次保存一种类型的值。”,正如评论所暗示的那样。这意味着元组的数据可以共存,而联合的数据则不能。
因此,如果您不想使用元组,但坚持使用联合,则需要更改您的类并使联合对世界其他地方可见。现在它是私有的,即使你得到它,使用getter函数,你的类外的世界也看不到联合,因此无法使用它。但是,事情变得有点复杂,所以我不明白为什么不使用元组。
可以找到工会的一个很好的例子here。正如预期的那样,它在C语言中,因为联合会在C语言中比在C ++中更频繁。
答案 2 :(得分:0)
为了扩展G.Samaras的答案,你可以这样做:
typedef std::tuple<type0, type1, type2, type3, type4> MyTuple;
MyTuple myTuple;
type0 a = std::get<0>(myTuple);
type1 b = std::get<1>(myTuple); //...etc.
(编辑:愚蠢......事实证明,您也可以这样做:
type0 a = std::get<type0>(myTuple);
type1 a = std::get<type1>(myTuple);
...留下答案的其余部分作为如何不承担事情的一个例子
那么如何将0与type0相关联,依此类推?你这样做(未经测试,但应该工作):
class MyTupleWrapper
{
private:
template <typename T> class TypeOffset {};
template <> class TypeOffset<type0> { enum { value = 0; } };
template <> class TypeOffset<type1> { enum { value = 1; } };
template <> class TypeOffset<type2> { enum { value = 2; } };
template <> class TypeOffset<type3> { enum { value = 3; } };
template <> class TypeOffset<type4> { enum { value = 4; } };
// ...etc
public:
typedef std::tuple<type0, type1, type2, type3, type4> MyTupleType;
explicit MyTupleWrapper(const MyTupleType& type) : _type(type) {}
template <typename T>
const T& Get() { return std::get< TypeOffset<typename T>::value >(_type); }
private:
MyTupleType _type;
}
要打破这个构造而不需要太多的实现,就是这样:
一个。您有两个工具 - std::tuple<Type1, Type2, ...>
专用类型和std::get<integer>(tupleObject);
来获取特定类型。整数参数取决于您定义元组的初始方式...所以如果您的数字是3,则返回值是该元组内部类型列表中的第三种类型(在我们的例子中,type3
)
湾元组本身支持正常分配...因此允许MyTupleType t; t = type1();
。但你不能调用type1 a = t;
- 它必须是type1 a = std::get<1>(t);
这是愚蠢的,因为你可以有很多元组类型,你不应该记住你在哪个位置定义了type1 in每个元组类型。
℃。这个包装器做了什么(打算做什么?)是能够说type1 a = t.Get<type1>();
使用模板重载将编译时中的每个类型转换为它的偏移量。