是否必须在模板中指定类型名称?

Does typename have to be specified inside template?

GCC 似乎不需要在模板中指定类型名称,而 Clang 需要。

考虑以下代码片段:

template<
    typename T,
    typename value_type = T::value_type
>
void func(T t) {}

上面的代码在 GCC 10.0.1 上编译成功,当 Clang 报告以下错误消息时:

❯ clang++ -std=c++20 asdf.cpp
asdf.cpp:3:27: error: missing 'typename' prior to dependent type name 'T::value_type'
    typename value_type = T::value_type
                          ^~~~~~~~~~~~~
                          typename
1 error generated.

为什么会这样?

更新 1:

正如@Language Lawyer 所指出的,关于 typename 的第一个怀疑是 Clang 目前不支持的 P0634R3 的一个特性。

更新 2:

我将把这个问题分开,因为它包含两个不同的主题。

查看编辑历史了解更多详情。

C++20 消除了在特定情况下为依赖模板名称指定 typename 的需要,在这些情况下,指定的内容显然 必须 是类型名称。例如,a template parameter's default value when that parameter has already specified that it is a typename:

A qualified name is said to be in a type-id-only context if it appears in [...] default argument of a type-parameter of a template, [...]

Clang has not yet implemented this feature,但 GCC 有。