模板化友元声明在 g++ 5.4.0 下不起作用——编译器错误或错误代码?
templated friend-declaration not working under g++ 5.4.0 -- compiler bug or bad code?
下面是一些 C++ 代码,在我的 Mac (Xcode 10.2 10E125 / Apple LLVM 版本 10.0.1 (clang-1001.0.46.4)) 但在我的 Linux 框 (g++ (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609 上给出了编译器错误消息(如下所示) ).
我的问题是,这是 g++ 5.4.0 中的编译器错误,还是我在代码中做错了什么?
g++ 5.4.0 的编译器错误是:
$ g++ template_friend.cpp
template_friend.cpp: In instantiation of ‘class SubClass<int>’:
template_friend.cpp:25:23: required from here
template_friend.cpp:10:10: error: ‘class BaseClass<int>::InnerClassFunctor’ is private
class InnerClassFunctor
^
template_friend.cpp:17:26: error: within this context
template <class T> class SubClass : public BaseClass<typename BaseClass<T>::InnerClassFunctor >
...重现错误的代码是:
template<class T> class BaseClass
{
public:
BaseClass(int) {}
private:
template<class HisT> friend class SubClass;
class InnerClassFunctor
{
public:
InnerClassFunctor() {}
};
};
template <class T> class SubClass : public BaseClass<typename BaseClass<T>::InnerClassFunctor >
{
public:
SubClass(int x) : BaseClass<typename BaseClass<T>::InnerClassFunctor >(x) {/* empty */}
};
int main(int, char **)
{
SubClass<int> table(0);
return 0;
}
虽然标准没有明确解决这种情况,但我认为这是一个 GCC 错误:它和 Clang 都没有正确实现 deferred access checking,尤其是 GCC 在模板参数方面存在问题(而且,显然,参数)。
下面是一些 C++ 代码,在我的 Mac (Xcode 10.2 10E125 / Apple LLVM 版本 10.0.1 (clang-1001.0.46.4)) 但在我的 Linux 框 (g++ (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609 上给出了编译器错误消息(如下所示) ).
我的问题是,这是 g++ 5.4.0 中的编译器错误,还是我在代码中做错了什么?
g++ 5.4.0 的编译器错误是:
$ g++ template_friend.cpp
template_friend.cpp: In instantiation of ‘class SubClass<int>’:
template_friend.cpp:25:23: required from here
template_friend.cpp:10:10: error: ‘class BaseClass<int>::InnerClassFunctor’ is private
class InnerClassFunctor
^
template_friend.cpp:17:26: error: within this context
template <class T> class SubClass : public BaseClass<typename BaseClass<T>::InnerClassFunctor >
...重现错误的代码是:
template<class T> class BaseClass
{
public:
BaseClass(int) {}
private:
template<class HisT> friend class SubClass;
class InnerClassFunctor
{
public:
InnerClassFunctor() {}
};
};
template <class T> class SubClass : public BaseClass<typename BaseClass<T>::InnerClassFunctor >
{
public:
SubClass(int x) : BaseClass<typename BaseClass<T>::InnerClassFunctor >(x) {/* empty */}
};
int main(int, char **)
{
SubClass<int> table(0);
return 0;
}
虽然标准没有明确解决这种情况,但我认为这是一个 GCC 错误:它和 Clang 都没有正确实现 deferred access checking,尤其是 GCC 在模板参数方面存在问题(而且,显然,参数)。