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

Extra typename keyword in template parameter list: is it valid or not?

本文关键字:关键字 typename 是否 有效 参数 列表      更新时间:2023-10-16

以下代码使用 clang 3.5.0g++ 4.9.0(带 -Wall -Wextra -pedantic-errors 标志(在 C++03(标志 -std=C++03(、C++11(标志 -std=C++11(和 C++14(标志 -std=C++14(下成功编译:

namespace N
{
    typedef int T;
    enum E{};
}
template <typename N::T>
struct ST{};
template <typename N::E>
struct SE{};
int main()
{
}

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


请注意,以下代码无法编译(如 C++03、C++11 和 C++14 代码(:

typedef int T;
enum E{};
template <typename T t>
struct ST{};
template <typename E e>
struct SE{};
int main()
{
}

但是下面的编译再次很好(C++03、C++11 和 C++14(:

typedef int T;
enum E{};
template <typename ::T>
struct ST{};
template <typename ::E>
struct SE{};
int main()
{
}

这是允许的,但仅限于限定名称:

类型名称说明符:
           typename嵌套名称说明符标识符
           typename嵌套名称说明符 template选择简单模板 ID

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

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

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

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

[ 注意:typename前缀一样,template 在非绝对必要的情况下,允许使用前缀;即, 当嵌套名称说明符或左侧的表达式 ->.不依赖于模板参数或使用 不显示在模板的范围内。— 尾注 ]

同样的音符存在于 C++14 标准中完全相同的位置。