在基类中访问朋友到受保护的函数 - 使用不同的编译器混合结果

时间:2016-12-09 12:33:47

标签: c++ c++11 gcc clang

考虑下面的代码(来自长期代码库的SSCCE) - 无法使用clangApple LLVM version 8.0.0 (clang-800.0.42.1))进行编译:

/Users/molleson/TestProject/test/test/main.cpp:17:15: error: 'foo' is a protected member of 'Base'
        Base::foo(t);
    ~~~~~~^~~
/Users/molleson/TestProject/test/test/main.cpp:36:6: note: in instantiation of member function 'Helper<X>::operator()' requested here
    h();
 ^
/Users/molleson/TestProject/test/test/main.cpp:6:36: note: declared protected here
    template <class T> static void foo(T&) {};

然而,多年来,它已经在包括gcc (g++ (GCC) 4.9.2)和SunStudio (SS12_3-20131030)

在内的多个平台上使用各种编译器进行了相当快乐的编译。

在构建SSCCE的过程中,我发现如果我将Helper::operator()()更改为常规成员函数(例如bar()),则会在所有编译器上失败,并发出与上述类似的警告。切换C ++标准似乎没有任何区别。

我不清楚这是否是一个格式正确的程序 - 特别是是否应该从派生类的朋友访问operator()(),以及是否有任何编译器不符合。

class Base
{
protected:    // <<-- compiles if public

    template <class T> static void foo(T&) {};
};

template <class T>
class Helper
{
public:
    void operator()()
    {
        T t;
        Base::foo(t);
    }
};

template <class T>
class Derived : public Base
{
template <class A>
    friend class Helper;
};

struct X
{
};

int main()
{
    Derived<X> d;
    Helper<X> h;
    h();
}

0 个答案:

没有答案