在对answer的评论中,Koushik提出了very valid point。
采取以下措施:
union U
{
int x;
const T y;
};
(我选择T
,这样在这里没有共同的布局兼容性初始序列,这意味着每个[C++11: 9.5/1]
在任何给定时间只有一个成员可能处于活动状态。)
由于任何时候只有一个成员可能处于“活动状态”(通过写入来激活),并且在初始化后无法写入y
,这不是没有意义吗?我的意思是,y
只能在第一次写入x
时读取,并且仅在y
是初始化成员时才会读取。
是否有一些用例我不见了?或者这确实是一种非常无意义的语言特征融合?
答案 0 :(得分:2)
确实有用:
1)提供类似const_cast
的技术。从某种意义上说,x = const_cast<...>(y)
。
2)处理模板时,有时您需要const
版本的数据类型,以便匹配其他参数类型。
(我已经看到(1)在针对传统接口进行编程时使用。)
答案 1 :(得分:2)
不使用工会很多,但这可能是这样的情况:
#include <iostream>
class Accessor;
union Union
{
private:
friend class Accessor;
int write;
public:
const int read;
Union() : read(0) {}
};
class Accessor {
public:
static void apply(Union& u, int i) { u.write = i; }
};
int main() {
Union u;
// error: ‘int Union::write’ is private
// u.write = 1;
std::cout << u.read << '\n';
Accessor::apply(u, 1);
std::cout << u.read << '\n';
}
注意:来自9.5联盟
注意:为了简化使用,我们提供了一项特殊保证 联合:如果标准布局联合包含多个标准布局 共享一个公共初始序列(9.2)的结构,以及一个对象 此标准布局联合类型包含标准布局之一 结构,允许检查任何共同的初始序列 标准布局结构成员;见9.2。 - 结束说明]
答案 2 :(得分:2)
这是一个参考语义类型的设计示例,您只需要授予const
访问权限。 union
用于从“类型擦除”函数返回的类似变体的数据类型。
#include <memory>
template<class T>
struct reference_semantics
{
public:
reference_semantics(T* p ) : m(p) {}
int observe() const { return *m; }
void change(T p) { *m = p; }
private:
T* m;
};
struct variant
{
enum T { INT, DOUBLE } type;
union U
{
reference_semantics<int> const i;
reference_semantics<double> const d;
U(int* p) : i(p) {}
U(double* p) : d(p) {}
} u;
};
#include <iostream>
std::ostream& operator<<(std::ostream& o, variant const& v)
{
switch(v.type)
{
case variant::INT:
return o << "INT: "<<v.u.i.observe();
case variant::DOUBLE:
return o << "DOUBLE: "<<v.u.d.observe();
}
}
#include <string>
variant type_erased_access(std::string name)
{
// imagine accesses to a map or so
static double dval = 42.21;
static int ival = 1729;
if(name == "Lightness") return { variant::DOUBLE, &dval };
else return { variant::INT, &ival };
}
int main()
{
variant v0( type_erased_access("Lightness") );
std::cout << v0 << "\n";
variant v1( type_erased_access("Darkness") );
std::cout << v1 << "\n";
}
现在想象一下,使用更大的数据类型而不是int
和double
,而reference_semantics
数据类型实际上提供的功能不仅仅是返回值。
甚至可能希望为某些参数返回reference_semantics<some_type> const
,而为其他参数返回普通int
。在这种情况下,您的union
甚至可能包含const和非const成员。
答案 3 :(得分:-1)
如果联合表示某些方法/算法的结果的一部分,那么它可能是有意义的。但在这种情况下,我会同时制作两个值const
:
union T
{
const int x;
const int y;
};