C++ C++;工会,两名活跃成员,仅因简历资格不同

C++ C++;工会,两名活跃成员,仅因简历资格不同,c++,language-lawyer,unions,C++,Language Lawyer,Unions,如果我有一个具有两个相同类型的数据成员的联合,则仅在CV资格方面有所不同: template<typename T> union A { private: T x_priv; public: const T x_publ; public: // Accept-all constructor template<typename... Args> A(Args&&

如果我有一个具有两个相同类型的数据成员的联合,则仅在CV资格方面有所不同:

template<typename T>
union A
{
    private:
        T x_priv;
    public:
        const T x_publ;

    public:
        // Accept-all constructor
        template<typename... Args>
        A(Args&&... args) : x_priv(args...) {}

        // Destructor
        ~A() { x_priv.~T(); }
};
这样,您就不需要getter函数,这可能会导致性能开销,尽管大多数编译器都会对此进行优化,但它仍然会增加您的类,要获取变量,您必须编写
int x=b.get_x()

您也不需要对该变量进行常量引用(如中所述),虽然它工作得很好,但会增加类的大小,这对于足够大的类或需要尽可能小的类来说可能是不好的

b.member.x_priv
而不是
b.x_priv
是很奇怪的,但是如果我们可以在匿名联盟中有私人成员,这是可以解决的,那么我们可以这样重写它:

struct B
{
    union
    {
        private:
            int x_priv;
        public:
            int x_publ;

        friend B;
    };

    void f() { x_priv = 100; }
}

int main()
{
    B b;
    b.f();            // Modifies the value of member.x_priv
    //b.x_priv = 100; // Invalid, x_priv is private
    int x = b.x_publ; // Fine, x_publ is public
}
另一个用例可能是给同一个数据成员赋予不同的名称,例如在一个形状中,用户可能希望将该位置称为
Shape.pos
Shape.position
Shape.cur\u pos
Shape.Shape\u pos


尽管这可能会产生更多的问题,但当例如一个名称应该被弃用时,这样的用例可能是有利的。

“我的问题是,这是否是无效行为的原因?”更好的问题是,它是否是有效行为的原因。这根本没有意义;您可以使用一个公共成员函数,该函数将
常量&
返回给私有成员。仅仅因为实现可能会让您逍遥法外,并不是一个很好的理由来定义某些东西。此外,我不确定当您询问某个功能的推理时,
语言律师
是否适用于标记。标准是什么;它没有解释为什么它是一种特定的方式。@Nicolas我不确定这个标记,但我选择包含它,因为第一点是关于如果标准重叠了它,我应该删除它吗?此外,我还编辑了一个问题,说明它是有效行为的原因
struct B;

struct A
{
     ... // Everything that struct A had before

     friend B;
}

struct B
{
    A member;

    void f() { member.x_priv = 100; }
}

int main()
{
    B b;
    b.f();                   // Modifies the value of member.x_priv
    //b.member.x_priv = 100; // Invalid, x_priv is private
    int x = b.member.x_publ; // Fine, x_publ is public
}
struct B
{
    union
    {
        private:
            int x_priv;
        public:
            int x_publ;

        friend B;
    };

    void f() { x_priv = 100; }
}

int main()
{
    B b;
    b.f();            // Modifies the value of member.x_priv
    //b.x_priv = 100; // Invalid, x_priv is private
    int x = b.x_publ; // Fine, x_publ is public
}