这段代码可以按预期在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

哪个编译器正确?如何解决?我正在尝试实现简洁的代码(没有外部 friend 方法),同时保持可移植性,灵活性和自记录代码。

一些注意事项:
  • 这是一个测试用例,用于显示问题,原始数据类型更加复杂和经过精心设计,尽管不能在MSVC中使用(主编译器为GCC,但也需要MSVC兼容性)。
  • 在联合声明的开头添加“public:”不会解决该问题。
  • 在每个操作符无法解决之前添加“public:”
  • 将测试用例转换为struct / class确实可以解决问题,但这不是所希望的(请您不要发火,我有理由。大多数是C++语言的局限性)
  • 运算符方法应保留在全局范围内(而不是成员函数)

  • 最佳解决方案不会出于不确定性原因而将声明移到并集定义之外(超过24种不同的运算符和操作数组合),但是如果没有其他解决方案,则可以这样做。

    最佳答案

    很难说哪一个是正确的,因为该标准不允许使用未命名的struct(尽管它们是常见的扩展名),因此该程序格式错误。

    编辑:这似乎是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;
    }
    

    您甚至可以通过在类中声明函数来保留 friend 状态(但仍在外部定义它们),但是我怀疑您是否需要在联合中使用它。

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

    关于c++ - MSVC: union 与内联好友运算符的类/结构,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1115464/

    10-09 05:58
    查看更多