同名的 typedef 和模板参数
typedef and template parameter with same name
为什么这种情况不正确(合乎逻辑)
template <typename T>
struct Der: public Base
{
typedef int T;
T val;
};
,但这种情况是正确的吗?
struct Base
{
typedef int T;
};
template <typename T>
struct Der: public Base
{
T val;
};
标准 14.6.1/7 说:
In the definition of a class template or in the definition of a member of such a template that appears outside of the template definition, for each base class which does not depend on a template-parameter (14.6.2), if the name of the base class or the name of a member of the base class is the same as the name of a template-parameter, the base class name or member name hides the template-parameter name (3.3.7).
为什么这里没有歧义?
根据 [temp.local]/6,第一个示例不正确:
A template-parameter shall not be redeclared within its scope (including nested scopes).
然而,在
template <typename T>
struct Der: public Base
{
T val;
};
T
隐藏在继承自 Base
的名称中 - 正如 引用 所指定的那样。
[..] if the name of the base class or the name of a member of
the base class is the same as the name of a template-parameter, the
base class name or member name hides the template-parameter name
(3.3.7).
即成员val
的类型为int
。 Demo.
因为第二个是明确的:
您可能不关心或不知道超类中有 typedev int T
,但您刚刚将 T
作为模板参数引入,这清楚地表明您指的是它在 Der
.
中使用 T
时
一般来说,标准试图确保一个类型的含义
给定的范围是相同的。
如果我们假设 typedef 是允许的,那么考虑下面的 val1
、val2
和 val3
类型?
template <typename T>
struct Der: public Base
{
void f1() {
T val1; // What is the type of 'val1'?
}
T val2; // What is the type of 'val2'?
typedef int T;
T val3; // What is the type of 'val3'?
};
唯一具有模板参数类型 T 的变量是
'val2'.
这是因为标准要求 class 的所有成员对于 f1
都是 "in scope"。这就是为什么成员函数可以引用稍后在 class 主体中定义的成员变量的原因。
同样的问题也可以用 typedef 来证明:
typedef int T;
struct S
{
T x;
typedef float T;
T y;
};
同样,如果这是合法的,那么用于声明 x
的 T
将引用 ::T
,而用于 y
的 T
将引用 typedef S::T
.
ISO 3.3.7/1 下的标准涵盖了这一点:
The following rules describe the scope of names declared in classes.
...
2) A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the completed scope of S. No diagnostic is required for a violation of this rule.
为什么这种情况不正确(合乎逻辑)
template <typename T>
struct Der: public Base
{
typedef int T;
T val;
};
,但这种情况是正确的吗?
struct Base
{
typedef int T;
};
template <typename T>
struct Der: public Base
{
T val;
};
标准 14.6.1/7 说:
In the definition of a class template or in the definition of a member of such a template that appears outside of the template definition, for each base class which does not depend on a template-parameter (14.6.2), if the name of the base class or the name of a member of the base class is the same as the name of a template-parameter, the base class name or member name hides the template-parameter name (3.3.7).
为什么这里没有歧义?
根据 [temp.local]/6,第一个示例不正确:
A template-parameter shall not be redeclared within its scope (including nested scopes).
然而,在
template <typename T>
struct Der: public Base
{
T val;
};
T
隐藏在继承自 Base
的名称中 - 正如 引用 所指定的那样。
[..] if the name of the base class or the name of a member of the base class is the same as the name of a template-parameter, the base class name or member name hides the template-parameter name (3.3.7).
即成员val
的类型为int
。 Demo.
因为第二个是明确的:
您可能不关心或不知道超类中有 typedev int T
,但您刚刚将 T
作为模板参数引入,这清楚地表明您指的是它在 Der
.
T
时
一般来说,标准试图确保一个类型的含义 给定的范围是相同的。
如果我们假设 typedef 是允许的,那么考虑下面的 val1
、val2
和 val3
类型?
template <typename T>
struct Der: public Base
{
void f1() {
T val1; // What is the type of 'val1'?
}
T val2; // What is the type of 'val2'?
typedef int T;
T val3; // What is the type of 'val3'?
};
唯一具有模板参数类型 T 的变量是 'val2'.
这是因为标准要求 class 的所有成员对于 f1
都是 "in scope"。这就是为什么成员函数可以引用稍后在 class 主体中定义的成员变量的原因。
同样的问题也可以用 typedef 来证明:
typedef int T;
struct S
{
T x;
typedef float T;
T y;
};
同样,如果这是合法的,那么用于声明 x
的 T
将引用 ::T
,而用于 y
的 T
将引用 typedef S::T
.
ISO 3.3.7/1 下的标准涵盖了这一点:
The following rules describe the scope of names declared in classes.
...
2) A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the completed scope of S. No diagnostic is required for a violation of this rule.