模板参数列表中的额外typename关键字:它是否有效?

时间:2014-10-25 15:30:33

标签: c++ templates c++11 c++14 typename

以下代码使用C++03 (flag -std=C++03)下的 clang 3.5.0 g ++ 4.9.0 (带有-Wall -Wextra -pedantic-errors标记)成功编译,{{ 3}}和C++11 (flag -std=C++11)

namespace N
{
    typedef int T;

    enum E{};
}

template <typename N::T>
struct ST{};

template <typename N::E>
struct SE{};

int main()
{
}

在非类型模板参数声明之前添加额外的typename关键字是否有效?


请注意,以下代码无法编译(如C++14 (flag -std=C++14)C++03C++11代码):

typedef int T;

enum E{};

template <typename T t>
struct ST{};

template <typename E e>
struct SE{};

int main()
{
}

但是下面一个会再次编译好(C++14C++03C++11):

typedef int T;

enum E{};

template <typename ::T>
struct ST{};

template <typename ::E>
struct SE{};

int main()
{
}

1 个答案:

答案 0 :(得分:6)

允许,但只能使用合格的名称:

  

typename-specifier:
typename nested-name-specifier identifier
typename 嵌套 - 名称说明符   template opt simple-template-id

根据语法,typename E是错误的。 typename N::E不是因为名称是合格的。第三种情况typename ::E很好,因为::是一个有效的嵌套名称说明符。

C ++ 03标准在[temp.res] / 5中指定

  

关键字typename仅适用于限定名称,但是   这些名字不一定要依赖。

C ++ 11标准明确说明了这一点,但在[temp.names] / 5的注释中:

  

[注意:typename前缀的情况一样,template   在不是绝对必要的情况下允许使用前缀;即,   当嵌套名称说明符或左边的表达式时   ->.不依赖于模板参数或使用   不会出现在模板的范围内。 - 结束记录]

同样的注释存在于C ++ 14标准的完全相同的位置。