GSi*_*GSi 7 c++ typedef language-lawyer name-lookup c++11
以下代码
#include <iostream>
typedef double A; // a global typedef
template <class Z> struct B // a template class...
{
A i{22.2}; // global typedef is in scope
typedef int A; // now a local typedef with the same name is introduced
A b{24}; // now the local typedef is in scope
Z c{36}; // a simple member of the template type
};
template <class Z> struct C : B<Z> // a template struct inheriting B
{
A a; // global typedef is in scope because we are in a template struct
C( ) : a(2.2){ }
};
int main( )
{
C<int> c;
std::cout << "c's members: "
<< c.a << ' '
<< c.i << ' '
<< c.b << ' '
<< c.c << std::endl;
std::cout << "their sizeof: "
<< sizeof(c.a) << ' '
<< sizeof(c.i) << ' '
<< sizeof(c.b) << ' '
<< sizeof(c.c) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
不是由GNU-g++ 4.9.2它编写的,而是clang 3.5.0按照我在嵌入式注释中尝试解释的行为,并且可以通过生成的输出看到它.这是GNU编译器中的错误吗?诊断说该行在typedef int A;范围内
struct B
错误:从'typedef double A'更改'A'的含义
请注意,当层次不进行的template(当然还有Z c{36};声明被移除)通过执行查找clang在范围C(正常,如我想)发现typedef在的范围B,认为所述构件a为类型int; 然后它发出关于缩小初始化double常数的警告2.2......
来自c ++标准草案(N4140)
§3.3.7[basic.scope.class]
2)在S类中使用的名称N应在其上下文中引用相同的声明,并在完成的S范围内重新评估.违反此规则不需要诊断.
A i{22.2}最初指的是全球性的::A.但是在B::A声明之后,当在完成的范围内重新评估时B,它将参考B::A.这违反了上述规则.
要修复它,请使用完全限定名称:::A i{22.2}.即使声明后::A总是指全局,所以它不违反规则.AB::A
这不是g ++中的错误; 这只是一个不合理的计划.编译器不需要为违反规则提供诊断,但也不需要接受它.
| 归档时间: |
|
| 查看次数: |
184 次 |
| 最近记录: |