是否依赖于本地类(如果在函数模板中声明)
Is a local class dependent if declared within a function template?
当前C++编译器(最新的gcc,clang)在下面的示例中需要typename
关键字:
template<class T>
struct A
{
};
template<class T>
void f(T)
{
struct C
{
};
typedef typename A<C>::Type Type; // typename required
}
如果省略typename
gcc (4.9, 5.0) 将报告错误:
need 'typename' before 'A<f(T)::C>::Type' because 'A<f(T)::C>' is a dependent scope
根据我对 C++11 标准的解读,此示例的格式良好。
以下措辞似乎涵盖了这种行为:
[温度类型]/8
如果类型是
模板参数,
未知专业的成员,
- 符合 CV 条件的类型,
作为当前实例化成员的嵌套类或枚举,
其中 CV 不合格类型是相关的,
由任何依赖类型构造的复合类型,
从任何依赖类型构造的数组类型,或者其大小由常量表达式指定 这是值依赖的,
简单模板 ID,其中模板名称是模板参数或任何模板 参数是依赖类型或依赖于类型或值的表达式,或者
由 decltype(expression) 表示,其中表达式与类型相关。
但是,根据 [class.local] 的说法,类C
是本地类而不是嵌套类。如果是这样,为什么要将A<C>
视为受抚养人?
编辑
对于奖励积分,如果通过将成员枚举添加到C
来修改示例,如下所示:
template<typename T>
struct A
{
typedef T Type;
};
template<class T>
void f(T)
{
struct C
{
enum { value = T::value };
};
typedef typename A<C>::Type Type; // typename required
}
A<C>
现在应该被视为受抚养人吗?
根据我的理解(以及标准的当前措辞),您示例中的C
不依赖于。两者都不是A<C>::Type
,所以typename
不是必需的。
之间存在根本区别:后者不能专用化,因此对函数模板中本地类的任何引用都是统一的。也就是说,在f
的每个专用化中,C
是指在此函数模板f
中定义的类C
。类模板不是这种情况,因为您确实可以显式地将成员专用化(如 [temp.expl.spec] 中所述)/(1.6)):
template <typename T>
class A { class C{}; };
template <>
class A<int>::C { int i; };
然而:
如果类型是
- 由任何依赖类型构造的复合类型,
因此,如果定义是按照 dyp 的示例完成的,C
将是依赖的,因为它是由 T
构造的。
评论部分正在讨论的标准措辞中存在不明确之处,例如,关于依赖于T
的成员函数的定义以及如何将其转换为类依赖项。
以下是我的推理,希望对您有所帮助。本地C
在f
实例化之前不会实例化。因此,A<C>
不是实例化,并且在编译器看到它时对它不透明。由于不透明性,编译器无法确定A<C>::Type
是嵌套类型名称、数据成员还是方法。但是,默认情况下,编译器不会将A<C>::Type
视为嵌套类型名称。因此,需要一个明确的规范。
标准中似乎没有任何内容表明 typename
关键字在这里应该是必需的。该措辞也没有明确说明其他内容,这可能导致GCC在将f<T>(T)::C
(作为函数模板专用化中的本地类)视为依赖于T
方面采取了一些捷径 - 通过扩展,这将使A<[f<T>(T)::]C>::Type
依赖。
核心缺陷 1484 没有专门针对这个问题提出,但我认为它提出的附加非规范性文本明确了意图,如果它在标准中,GCC 将合规地不需要这里的 typename
关键字。
- 如何使用模板声明成员函数?(不是模板类)
- 我应该声明我的函数模板专业化还是定义它们就足够了
- 模板函数可以使用带有删除的构造函数的声明类型
- 使用非类型模板参数正向声明函数模板
- 如何声明接受转发引用并返回引用或副本的函数模板
- 如何在C 中声明外部CUDA函数模板
- 模板化成员函数的声明和实现
- SFINAE 消除、Constexpr 和函数模板:我可以将声明和定义分开吗?
- MISRA C++规则 14-5-1:在与类型关联的命名空间中声明的泛型函数模板的名称
- 模板声明中省略了c++类型参数.然而,在成员函数的定义中呢
- 从单独的文件转发模板函数的声明
- 如何将函数指针声明指向模板函数,其返回类型取决于模板类
- 'Incomplete type' 为标准::函数声明指向成员的指针函数模板参数时出错
- 声明函数模板的5种新语法是什么
- 模板类中专用函数的声明
- 是否依赖于本地类(如果在函数模板中声明)
- 如何在将函数作为参数传递给文件中.cpp函数模板时声明
- C++模板基类的非类型函数模板的 using 声明
- 函数模板错误 -- 尚未声明
- c++类和函数模板声明