typedef Foo<> Foo编译但是有效吗?

时间:2014-10-17 18:25:28

标签: c++ templates typedef

以下位代码在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
}

有效吗?

2 个答案:

答案 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;