考虑下面的代码(来自长期代码库的SSCCE) - 无法使用clang
(Apple 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();
}