如何解决尝试通过使用带有虚拟参数的模板别名隐藏基类来混淆clang和gcc时,行为上的差异
请考虑以下c ++程序:
class A
{
protected:
int x;
};
template<typename X>
using B = A;
template<typename T>
class C : public B<T>
{
public:
void f()
{
x = 0;
}
};
int main()
{
}
在使用-std=c++17 -pedantic-errors
作为编译选项的clang和gcc进行编译时,它们的行为有所不同:Clang编译没有任何错误,但gcc给出了有关无法查找标识符x
的编译错误。
在这种情况下,c ++标准怎么说?是否允许两种行为,或者其中一种编译器在这种情况下有错误?
编译器资源管理器链接:https://godbolt.org/z/EYvYrr
解决方法
这看起来与CWG1390类似,并且看起来Clang的行为与CWG关于如何处理此类别名模板的协议一致(在模板定义时急切替换):
,1390。别名模板专业化的依赖性
根据17.7.2.1 [temp.dep.type]第8段,类型(除其他外)是从属的,
- 一个 simple-template-id ,其中模板名称是模板参数,或者任何模板参数是从属类型或与类型或值相关的表达式
这适用于别名模板专业化,即使结果类型不取决于模板参数:
struct B { typedef int type; }; template<typename> using foo = B; template<typename T> void f() { foo<T>::type * x; //error: typename required }
是否有必要更改此类案件的规则?
2012年10月会议的笔记:
CWG同意在这种情况下不需要
typename
。在某些方面,别名模板特化类似于当前实例化,并且可以在模板定义时就知道。
对于C ++ 17,此处的GCC是正确的。
9类型是否依赖
模板参数
[...]
一个 simple-template-id ,其中模板名称是模板参数,或者任何模板参数是从属 类型或表达式,它取决于类型或值,或者 包扩展[注:这包括一个注入的类名 没有template-argument-list的类模板。 — [请注意], 或
B<T>
是一个简单模板ID,其参数是从属类型,因此B<T>
表示的类型是从属类型。使用从属类型作为基类时,任何继承的成员必须通过其基类名称完全限定,或通过this->
访问。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。