以下位代码在VS2008和GCC 4.8.2中编译
template<typename T=void>
struct Foo
{
};
// typedef Foo<> Foo; // Does *NOT* compile
int main()
{
typedef Foo<> Foo;
Foo f1;
// Foo<char> f2; // Does *NOT* compile
//::Foo<char> f3; // COMPILES
}
有效吗?
答案 0 :(得分:17)
根据C ++ 11 3.3.10 / 1:
可以通过嵌套声明区域中相同名称的显式声明隐藏名称或派生名称 类。
(强调我的)
这就是为什么模板名称Foo
可以被Foo
内的typedef名称main()
(不同的范围)隐藏,但与模板的范围不同名称已声明。
至于为什么这种类似的案件是合法的:
struct Foo
{
};
typedef Foo Foo; // *DOES* compile
7.1.3 / 3明确允许:
在给定的非类范围内,可以使用
typedef
说明符重新定义在该范围内声明的任何类型的名称 范围,以指代它已经引用的类型。
答案 1 :(得分:11)
是的,它有效,原因与此有效:
struct Foo { };
namespace bar {
struct Foo { };
}
您只是覆盖了不同范围内的名称。在main中,您仍然可以执行以下操作:
::Foo<int> f2;