Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果在函数模板中声明,是否依赖于本地类? 当前C++编译器(最新的GCC,CLAN)需要下面的例子中的类型名称< /Cord>关键字: template<class T> struct A { }; template<class T> void f(T) { struct C { }; typedef typename A<C>::Type Type; // typename required }_C++_Templates_Language Lawyer_Typename_Local Class - Fatal编程技术网

如果在函数模板中声明,是否依赖于本地类? 当前C++编译器(最新的GCC,CLAN)需要下面的例子中的类型名称< /Cord>关键字: template<class T> struct A { }; template<class T> void f(T) { struct C { }; typedef typename A<C>::Type Type; // typename required }

如果在函数模板中声明,是否依赖于本地类? 当前C++编译器(最新的GCC,CLAN)需要下面的例子中的类型名称< /Cord>关键字: template<class T> struct A { }; template<class T> void f(T) { struct C { }; typedef typename A<C>::Type Type; // typename required },c++,templates,language-lawyer,typename,local-class,C++,Templates,Language Lawyer,Typename,Local Class,A现在应该被视为依赖吗?以下是我的推理,希望能有所帮助。本地C在f实例化之前不会实例化。因此,A不是一个实例化,当编译器看到它时,它是不透明的。由于不透明,编译器无法确定A::Type是嵌套类型名还是数据成员或方法。但是,默认情况下,编译器不会将A::Type视为嵌套类型名。因此,需要一个明确的规范。根据我的理解(以及标准的当前措辞),C在您的示例中是不相关的。两者都不是A::Type,因此不需要typename 类模板的嵌套类和函数模板中的本地类之间有一个根本区别:后者不能专门化,因此函数模板

A
现在应该被视为依赖吗?

以下是我的推理,希望能有所帮助。本地
C
f
实例化之前不会实例化。因此,
A
不是一个实例化,当编译器看到它时,它是不透明的。由于不透明,编译器无法确定
A::Type
是嵌套类型名还是数据成员或方法。但是,默认情况下,编译器不会将
A::Type
视为嵌套类型名。因此,需要一个明确的规范。

根据我的理解(以及标准的当前措辞),
C
在您的示例中是不相关的。两者都不是
A::Type
,因此不需要
typename

类模板的嵌套类和函数模板中的本地类之间有一个根本区别:后者不能专门化,因此函数模板中对本地类的任何引用都是统一的。也就是说,在
f
的每个专门化中,
C
指在该函数模板
f
中定义的类
C
。类模板并非如此,因为您确实可以自己显式地专门化成员(如[temp.expl.spec]中所述) /(1.6)):

模板
A类{C类{};};
模板
类A::C{int i;};
然而:

如果类型是依赖的,则它是依赖的

  • 由任何依赖类型构造的复合类型
因此,如果定义按照中的方式进行,
C
将是依赖的,因为它是根据
T
构建的

评论部分讨论的标准措辞中存在不一致之处,例如,关于依赖于
T
的成员函数的定义,以及如何将其转换为类依赖关系。

标准中似乎没有任何规定此处需要使用
typename
关键字。措辞也没有明确说明其他情况,这可能导致GCC在处理
f(T)::C
(作为函数模板专业化中的一个本地类)时采取了一些捷径,因为它依赖于
T
——扩展而言,这将使
a::Type
依赖


没有专门针对这个问题提出,但我认为它提出的附加非规范性文本明确了意图,如果是在标准中,GCC将不要求此处使用
typename
关键字。

这似乎与DR 1484有关:他们使用DR页面上的锚,因此,您可以直接提供指向特定缺陷的链接:我认为需要
typename
。考虑一些奇怪的例子:我们可以根据模板参数来定义<代码> c>代码>,即使它的名称不是。[TEMP.DEP.Type ] / 8 ->啊,谢谢。所以你漏掉了一些要点。不过,据我所知,这些建议似乎都不适用。在我看来,这似乎是标准中的一个疏忽。这似乎是正确的,但是问题被标记为语言律师,并引用了标准,所以你需要用语言的官方规则来支持你的主张。@BartoszKP你是对的。不管怎样,这里有一些你感兴趣的猜测。编译器生成的错误消息似乎表明,如果嵌套类型的作用域是依赖类型,则即使它本身不是依赖类型,也需要显式的规范。我猜在这种情况下,不管嵌套类型的范围如何,它是否应该实例化都是由实现定义的。我不想讨论这个问题,我只是想鼓励您改进您的答案:)正如您在Columbo的答案中所看到的,声称它是“实现定义的”无论如何都是错误的,模板类中定义的所有嵌套类都是依赖的。在
模板结构A{struct B{};void f(){B B;}
,您发现的措辞更改不会使
B
不相关。它不能,因为可能会有一个专业化,例如
a::B
。但是我认为我现在同意你的观点,本地类可以是非依赖的。你可以专门化
A::B
,即使不专门化
A
模板结构A{struct B{int&&m;};void f(){B B;};模板结构A::B{};int main(){A().f();}
完全有效。@hvd Ahh,你是对的。“名称是当前实例化的依赖成员,如果它是当前实例化的成员,并且在查找时引用了作为当前实例化的类的至少一个成员。”我将很快编辑我的答案。我们可以确定本地类是否依赖于该类吗?例如,
struct C{auto foo(){return std::conditional::type{};}
@dyp乍一看,
C
是不依赖的,但是
C::foo
是依赖的。
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
}
template <typename T>
class A { class C{}; };

template <>
class A<int>::C { int i; };