c++ - MSVC 是否错误地处理依赖名称中的模板关键字?

标签 c++ templates language-lawyer

知乎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/

相关文章:

c++ - Boost Spirit 和抽象语法树设计

c++ - 具有 std::enable_if 和具体类型的模板类特化

c++ - 模板基类型继承

有和没有主体的 C++ 部分构造函数表现不同

c++ -/usr/bin/ld : cannot find -lopencv_contrib

c++ - 如何在 GDB 中访问 std::tr1::shared_ptr 的目标

c++ - 使用 OpenGL 绘制多个对象时遇到问题

c++ - 声明函数模板的语法

c++ - `decltype` 在 lambda 体内的广义 lambda 捕获 - gcc vs clang

bash - 替代 for 循环构造