我最近被(简化)咬了
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++代码对私有成员使用丑陋的名称)。
PS:我没有深入研究这个问题的标准,但 g++ 和 clang++ 都同意这种行为,所以我不认为这是一个错误。
PPS:在实际代码中,被隐藏的模板参数名为tid
,并且是整数而不是类型。-Wall
不足以通知隐藏,我在用 valgrind 调试几个小时后发现了它。