MSVC 错误?尽管有模板友元声明,模板友元函数仍无法访问私有成员

Pit*_*taJ 5 c++ templates visual-c++ compiler-bug

我有以下 C++ 代码:

template<typename T>
class Foo;

template<typename T, typename U>
Foo<T> operator+(Foo<T> lhs, const Foo<U>& rhs);

template<typename T>
class Foo {
    template<typename>
    friend class Foo;

    T inner;

public:
    Foo(T i) : inner(i) {}

    template<typename U>
    friend Foo<T> operator+(Foo<T> lhs, const Foo<U>& rhs) {
        lhs.inner += rhs.inner;
        return lhs;
    }
};

int main() {
    Foo<int> a = 4;
    Foo<unsigned> b = 5;
    Foo<int> c = a + b;
}
Run Code Online (Sandbox Code Playgroud)

神箭

它可以使用 GCC 和 clang 正常编译,但在 MSVC v19.37 和 Visual Studio 2015 中编译失败并出现错误:

example.cpp
<source>(19): error C2248: 'Foo<unsigned int>::inner': cannot access private member declared in class 'Foo<unsigned int>'
<source>(12): note: see declaration of 'Foo<unsigned int>::inner'
<source>(26): note: see declaration of 'Foo<unsigned int>'
<source>(27): note: see reference to function template instantiation 'Foo<int> operator +<unsigned int>(Foo<int>,const Foo<unsigned int> &)' being compiled
<source>(27): note: see the first reference to 'operator +' in 'main'
Compiler returned: 2
Run Code Online (Sandbox Code Playgroud)

这似乎是 MSVC 的某种问题。有解决方法吗?还是我还缺少其他东西?

Pit*_*taJ 0

我发现的最佳解决方案是将实际实现移至静态方法中,并在友元函数内调用该静态方法:

template<typename T>
class Foo {
    template<typename>
    friend class Foo;

    T inner;

    template<typename U>
    static Foo op_add(Foo lhs, const Foo<U>& rhs) {
        lhs.inner += rhs.inner;
        return lhs;
    }

public:
    Foo(T i) : inner(i) {}

    template<typename U>
    friend Foo operator+(Foo lhs, const Foo<U>& rhs) {
        return op_add(lhs, rhs);
    }
};
Run Code Online (Sandbox Code Playgroud)

神箭