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++ 结构声明被变量隐藏时的名称解析 我们考虑下面的演示程序。 #include <iostream> struct A { struct B { int b = 10; }; int B = 20; }; template <class T> struct C { void f() const { typename /*struct*/ T::B b; int x = b.b; std::cout << "x == " << x << '\n'; } }; int main() { C<A>().f(); }_C++_Templates_C++17_Dependent Name_Name Hiding - Fatal编程技术网

C++ 结构声明被变量隐藏时的名称解析 我们考虑下面的演示程序。 #include <iostream> struct A { struct B { int b = 10; }; int B = 20; }; template <class T> struct C { void f() const { typename /*struct*/ T::B b; int x = b.b; std::cout << "x == " << x << '\n'; } }; int main() { C<A>().f(); }

C++ 结构声明被变量隐藏时的名称解析 我们考虑下面的演示程序。 #include <iostream> struct A { struct B { int b = 10; }; int B = 20; }; template <class T> struct C { void f() const { typename /*struct*/ T::B b; int x = b.b; std::cout << "x == " << x << '\n'; } }; int main() { C<A>().f(); },c++,templates,c++17,dependent-name,name-hiding,C++,Templates,C++17,Dependent Name,Name Hiding,不应找到依赖的名称T::B 但是,编译器gcc 8.3成功编译程序并输出程序 x == 10 另一方面,编译器 Visual C++ 2019 不会编译程序并发出语法错误。 那么它是编译器gcc 8.3的一个bug吗 第二个问题是,如果允许使用带有详细类型说明符的这种构造(带有未注释的关键字struct),这是很自然的 typename struct T::B b; 但是两个编译器都认为结构不正确。 它确实不正确吗?从我的观点来看:在f()函数中,您需要声明struct以避免此问题 temp

不应找到依赖的名称
T::B

但是,编译器
gcc 8.3
成功编译程序并输出程序

x == 10

另一方面,编译器<强> Visual C++ 2019 不会编译程序并发出语法错误。

那么它是编译器gcc 8.3的一个bug吗

第二个问题是,如果允许使用带有详细类型说明符的这种构造(带有未注释的关键字struct),这是很自然的

typename struct T::B b;
<>但是两个编译器都认为结构不正确。


它确实不正确吗?

从我的观点来看:在f()函数中,您需要声明struct以避免此问题

template <class T> struct C {
        void f() const {
            // just normal struct
            struct T::B structB;
            int x = structB.b;
    
            std::cout << "x == " << x << std::endl;
    }
};
模板结构C{
void f()常量{
//正态结构
结构T::B结构B;
int x=结构b.b;

std::cout这应该是编译器gcc 8.3的一个缺陷。因为
typename T::B
的标准规则应解析为变量,而不是
struct B
,这些规则如下所示:

类名或枚举名可以通过在同一作用域中声明的变量、数据成员、函数或枚举数的名称隐藏。如果类或枚举名和变量、数据成员、函数或枚举数在同一作用域中声明(按任意顺序)如果使用相同的名称,则无论变量、数据成员、函数或枚举器名称在何处可见,都会隐藏类或枚举名称

上面的规则表示,
struct B
的名称被声明的名称
int B=20;

当限定id要引用的类型不是当前实例化的成员时([temp.dep.type])它的嵌套名称说明符是指依赖类型,它的前缀应该是关键字typename,形成typename说明符。如果typename说明符中的限定id不表示类型或类模板,则程序的格式不正确

常规限定名查找用于查找限定id,即使存在typename

上述规则表示关键字
typename
不影响
限定名称查找的结果
,换句话说,关键字
typename
不要求名称查找过程只查找类型

因此,在
A
的范围内,可以找到
int B=20;
struct B
的声明,然后变量隐藏
类名
。因此,根据规则如果typename说明符中的限定id不表示类型或类模板,则程序是格式不正确的,程序应该ld格式不正确。因此,GCC 8.3是错误的


此外,不仅代码> GCC 8.3 而且更高版本都是错误的。< / P>不正确。复杂类型说明符的正确用法将是“代码>结构T::BB;<代码> >代码> >类型名称< /代码> @ @ StruytLeunSand 17,但根据C++标准“2在模板声明或定义中使用的依赖于模板参数的名称被假定为不命名类型,除非适用的名称查找找到类型名称或名称由关键字typename限定。”这是关键字typename是必需的。同样根据C++17标准”在类或decltype或详细类型说明符中用作名称的限定名称隐式假定为类型名称,而不使用typename关键字。在立即包含依赖于模板参数的嵌套名称说明符的嵌套名称说明符中,标识符或简单模板id隐式假定为名称类型,不使用typename关键字[ 注意:这些构造的语法不允许使用typename关键字。 — 尾注 ]“因此,不仅不需要@StoryTeller UnslanderMonica,而且不允许@StoryTeller UnslanderMonica作为一个好的参考。我还没有阅读这一段。

template <class T> struct C {
        void f() const {
            // just normal struct
            struct T::B structB;
            int x = structB.b;
    
            std::cout << "x == " << x << std::endl;
    }
};
C<A> j; 
// call
j.f();