【发布时间】:2015-06-04 10:26:16
【问题描述】:
我最近被(简体)咬了
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 调试几个小时后发现了它。
【问题讨论】:
-
你用不同的编译器试过了吗?很高兴知道这是与实现相关、标准中的粗心还是实际意图。
-
@stefaanv 这是标准化行为,当然不是粗心大意。
-
可能是因为依赖名和独立名。见this也许对你有帮助。
-
单字母变量是个坏主意。我什至避免使用一个字母模板变量。他们隐藏意图。一封信不会向读过密码的可怜的混蛋透露任何信息。包括你自己在内的那个可怜的混蛋。这样做是为了避免被咬。
-
@PhilipStuyck:在实际代码中,被隐藏的模板参数被命名为
tid,它是一个整数而不是一个类型。-Wall不足以通知隐藏,我在使用 valgrind 调试几个小时后发现了它。
标签: c++ templates language-lawyer name-lookup name-hiding