知乎Where and why do we have to put the template
and typename
keywords , 我很惊讶地得知 MSVC accepts以下代码:
struct foo {
using bar = int;
};
template <typename T>
void quux() {
T::template bar b;
}
int main() {
quux<foo>();
}
据我了解,T::template bar b;
的用法是不正确的。正确的申报方式b
将使用 typename
,像这样:typename T::bar b;
(而不是 T::template bar b;
)。 template
意味着 bar
是一个,嗯,一个模板,但事实并非如此。是 MSVC 中的错误导致它接受不正确的代码,还是标准允许并且 Clang 和 GCC 都没有以这种方式实现它(因此需要正确使用
typename
在这里)?
最佳答案
MSVC 有一个长期存在的错误 - 当我询问您链接的模板类型名称问题时,它已经是一个旧错误。简而言之,自 1998 年以来的 C++ 要求在模板中进行两阶段名称查找。在第一阶段,当模板本身被编译时,只查找不相关的名称,因为实际的模板参数尚不清楚。在第二阶段,查找依赖名称(有关详细信息,请参阅链接的问题)。
但是 MSVC 不会这样做,并且会在实例化模板时进行所有查找。在您的情况下,这意味着所有查找都在 MSVC 编译 quux<foo>
时完成。 ,编译时什么也没有quux<T>
.因为它不做第一阶段,所以它不需要 typename
在依赖名称上。 MSVC 已经知道 quux::b
.
似乎 MSVC 走得更远。它不仅忽略了正确的 typename
,但它也忽略了 template
的错误使用就像在这个例子中一样。忽略事物时,这并不完全令人惊讶。
关于c++ - MSVC 是否错误地处理依赖名称中的模板关键字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68806285/