Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.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++ 类型名c++;编撰顺序_C++_Typename - Fatal编程技术网

C++ 类型名c++;编撰顺序

C++ 类型名c++;编撰顺序,c++,typename,C++,Typename,在本文中,与关键字Typename的使用相关的内容是: 模板 void foo(施工测试与测试) { //声明指向类型为T::bar的对象的指针 T::bar*p; } struct StructWithBarAsType{ 输入条; }; int main(){ 带Barastype x的结构; foo(x); } 事实上,在StructWithBarAsType中,依赖条实际上是一个 类型没有帮助,因为foo()可能早在 可以看到带有BarasType的结构 我不理解为什么FoE()可以在

在本文中,与关键字Typename的使用相关的内容是:

模板
void foo(施工测试与测试)
{
//声明指向类型为T::bar的对象的指针
T::bar*p;
}
struct StructWithBarAsType{
输入条;
};
int main(){
带Barastype x的结构;
foo(x);
}
事实上,在StructWithBarAsType中,依赖条实际上是一个 类型没有帮助,因为foo()可能早在 可以看到带有BarasType的结构


我不理解为什么FoE()可以在StructWithBarAsType之前编译,在这种情况下,它可以是这样的。

< P>当编译器解析C++文件时,它通常会为类型建立标识符的符号表。当调用模板时,这是很重要的,因为C++编译器将基本上做一个“替换检查”,以确保“所有的事情都能解决”。 问题在于这种模棱两可的说法:

T::bar*p;
这可以解释为:

  • 类型
    T
    上的静态成员变量命名为
    bar
    乘以
    p
    ?运算符*(?T::bar,?p)
  • 声明一个名为
    p
    T::bar*
    类型的指针
  • 这会在解析时产生某种歧义,并导致编译器错误:

    g++main.cpp&&./a.out
    main.cpp:在函数“void foo(const T&)”中:
    main.cpp:9:13:错误:“p”未在此范围内声明
    9 | T::bar*p;
    |             ^
    main.cpp:在“void foo(const T&)[with T=StructWithBarAsType]”的实例化中:
    main.cpp:14:9:此处需要
    main.cpp:9:11:错误:依赖名称“T::bar”被解析为非类型,但实例化会生成一个类型
    9 | T::bar*p;
    main.cpp:9:11:注意:如果某个类型的意思是
    
    main.cpp:9:11:错误:依赖名称“T::bar”被解析为非类型,但实例化会生成一个类型

    为了清除这个解析错误,C++对“信号”有一个“语法修改”,即模板中的标识符是类型名而不是变量名。这种“语法修改”的形式是

    typename

    structStructWithBarasType{
    输入条;
    };
    模板
    void foo(施工测试与测试)
    {
    //声明指向类型为T::bar的对象的指针
    typename T::bar*p;
    }
    int main(){
    带Barastype x的结构;
    foo(x);
    }
    
    这就是编译


    <>请注意,C++中的语法分析也会遇到类似的问题。请参阅.p/>请阅读。当链接死或内容改变时,问题对未来读者来说毫无意义。“超级模糊的评论。你应该做的是发布他们提到的代码,所以如果链接已经死了或者被改变了,你的问题就有意义了。”因为我的问题不同,实质上我问为什么编译器不能看到StructWithBarAsType定义并解决歧义可以在StructWithBarAsType之前很久编译,我问为什么会这样。你问为什么编译器不这样做,我想另一个问题的这一段给了你一个答案:这会起作用,实际上是标准允许的一种可能的实现方法。这些编译器[…]当需要实例化时,他们会解析模板,并可能检测到定义中的错误。但不会打扰模板的用户(可怜的同事!)由于模板的作者犯了错误,其他实现会选择尽早检查模板,并在实例化之前尽快给出定义中的错误。感谢您的确认,我将投票支持您的问题是另一个问题的副本。好的,但是当编译看到“foo(x)”时“如果x类型为StructWithBarAsType,则无法在StructWithBarAsType定义中查看并解决歧义?Wiki说,因为foo()可以在StructWithBarAsType之前编译,我问为什么会出现这种情况。创建一个编译器来解决这种歧义是不可能的?不完全确定,但我想重点应该放在“解析时间保证”上。通过添加
    typename
    ,您为模板配备了
    T::Bar is-一种类型的
    关联,它是帮助编译器验证和连接点与foo(x)
    中的
    StructWithBarAsType::Bar,T=StructWithBarAsType的必要关联。编译器可以这样做:当f(x)为已调用查看x的类型,该类型为StructWithBarAsType,因此使用StructWithBarAsType信息编译模板,然后在不使用typename的情况下解决歧义。可能是由于技术原因,调用f(x)后无法始终解析模板。