[英]Template parameter name hiding
我最近被咬了(简化)
struct Base {
typedef char T;
};
template<typename T>
struct Foo : Base {
T x[50]; // This is Base::T, not the template parameter
};
换句话说,类成员名称隐藏模板参数(即使来自基类,因此在本地上下文中并不完全明显)。
然而,我做了一些实验,发现:
struct Base {
typedef char T;
};
template<typename T, typename B>
struct Foo : B {
T x[50]; // This T is the template parameter,
// even passing Base as B
};
我能想到的唯一出路是给出丑陋的模板参数名称,也意味着在不使用保留名称的情况下安全地编写模板是不可能的(因为模板中使用的类可能会碰撞参数名称...请注意很多C ++代码使用uglyfied名称为私人成员)。
PS:我没有深入研究这个问题的标准,但是g ++和clang ++都同意这个行为,所以我认为这不是一个错误。
PPS:在实际代码中,隐藏的模板参数名为tid
,是一个整数而不是一个类型。 -Wall
还不足以告知隐藏,我在用valgrind进行了几个小时的调试后发现了它。
此规则(在[temp.local] / 9中指定)是11年前创建的开放核心语言问题的主题 - 核心问题#459 。 CWG彻底讨论了这个问题。 关于意图,迈克米勒提到了这一点
当前规范的基本原理非常简单:
“除非在派生类中重新声明,否则基类的成员也被认为是派生类的成员。”(10 [class.derived]第2段)
在类范围中,成员隐藏非成员。
而已。 因为模板参数不是成员,所以它们被成员名称隐藏(无论是否继承)。 我没有发现“奇怪”,甚至特别令人惊讶。
理由:
我们对改变有一些同情,但是当前的规则直接落在查找规则之外,因此它们并非“错误”。使私有成员不可见也会解决这个问题。 我们愿意看一篇提出这个问题的论文。[...]
如果没有更详细地探讨该问题的论文,CWG决定此时不考虑更改现有规则。
不幸的是,还没有写过这样的论文,所以规则一直持续到今天。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.