MSVC:工会与内联友商类/结构(MSVC: union vs. class/struct with

2019-10-16 21:58发布

这段代码编译并运行在GCC 3.x和4.x预期:

#include <stdio.h>

typedef union buggedUnion
{   
public:
            // 4 var init constructor
        inline buggedUnion(int _i) {
            i = _i;
        }

        friend inline const buggedUnion operator - (int A, const buggedUnion &B) {
            return buggedUnion(A - B.i);
        }

        friend inline const buggedUnion operator - (const buggedUnion &A, const buggedUnion &B) {
            return buggedUnion(A.i - B.i);
        }

        int i;

} buggedUnion;

int main()
{
    buggedUnion first(10);
    buggedUnion second(5);

    buggedUnion result = 10 - (first - second);

    printf("%d\n", result.i); // 0

    return 0;
}

MSVC,但是,不会编译代码,抱怨:

main.cpp(60) : error C3767: '-': candidate function(s) not accessible
        could be the friend function at 'main.cpp(41)' : '-'  [may be found via argument-dependent lookup]
        or the friend function at       'main.cpp(45)' : '-'  [may be found via argument-dependent lookup]
main.cpp(60) : error C2676: binary '-' : 'buggedUnion' does not define this operator or a conversion to a type acceptable to the predefined operator

其编译器是正确的? 这又如何解决? 我试图达到清洁的代码(没有外界朋友的方法),同时保持便携性,灵活性和自我记录代码。

一些注意事项:

  • 这是一个测试案例来说明问题,原来的数据类型更加复杂和精心设计的,尽管在MSVC不工作(主要编译器GCC,虽然MSVC的兼容性也需要)。
  • 增加“市民:”在联合声明的开头不能解决它。
  • 增加“市民:”以前每个操作员不解决这个问题
  • 测试用例转换到结构/类完成修复它,但这是不希望的(请无火焰,我得到的原因。他们中的大多数是C的限制++语言)
  • 是在全局范围内进行操作者左方法(不是成员函数)

最佳的解决方案将不依赖于移动联盟定义aestetic原因(超过24符和操作数的不同组合)外的声明,但如果没有其他的解决方案来实现。

Answer 1:

这是很难说哪一个是正确的,因为未命名的struct s的不受标准允许的(尽管它们是共同的扩展名),并且这样的程序是非法的构造。

编辑 :这似乎是在MSVC的错误,因为下面的代码,这是完全合法的,无法编译。

union buggedUnion
{
    friend buggedUnion operator - (int A, const buggedUnion &B) {
        return B;
    }

    friend buggedUnion operator - (const buggedUnion &A, const buggedUnion &B) {
        return A;
    }

    int i;
};


int main()
{
    buggedUnion first = { 1 };
    buggedUnion second = { 1 };
    buggedUnion result = 3 - (first - second);
}

您可以通过定义类的外部功能解决这个问题。

union buggedUnion
{
    int i;
};

buggedUnion operator - (int A, const buggedUnion &B) {
    return B;
}

buggedUnion operator - (const buggedUnion &A, const buggedUnion &B) {
    return A;
}

你甚至可以通过声明函数的类中(但还在外面定义它们)保留了好友状态,但我怀疑你在任何时候需要,在一个联盟。

请注意,我删除了不必要typedefinline秒。



Answer 2:

下面的代码编译正确在Visual C ++ 2008:

union buggedUnion
{
    int i;

    friend buggedUnion operator - (int A, const buggedUnion &B);
    friend buggedUnion operator - (const buggedUnion &A, const buggedUnion &B);
};

buggedUnion operator - (int A, const buggedUnion &B)
{
    return B;
}

buggedUnion operator - (const buggedUnion &A, const buggedUnion &B)
{
    return A;
}

虽然MSDN文档指出编写友元函数的定义在类中其实是把该功能在文件范围内,这似乎不是工会工作。 由于它适用于类和结构,我怀疑这可能是一个错误。 上面我已经给应海湾合作委员会开展工作的情况,我认为它可以被视为一个合适的解决方法和错误可能不会被固定在MSVC。



Answer 3:

需要声明的友元函数在封闭范围内,因为一旦你在类中声明它们,它们不再显示在外部范围。 因此,无论移动功能体而出,该类用作avakar说,还是让他们在课堂上,并添加以下行的名称再引入封闭范围:

extern const buggedUnion operator-(const buggedUnion& A, const buggedUnion&B);

int main()
{
    ...etc

希望这可以帮助。 不知道它是否是一个错误,但它出现(?)对我来说是正确的行为,现在可以正确地实施,其中许多编译器用于解释不同。 请参阅:--ffriend注射在http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html 。



文章来源: MSVC: union vs. class/struct with inline friend operators