【问题标题】:MSVC: unrecognizable template declaration/definition (compiles with Clang/GCC)MSVC:无法识别的模板声明/定义(使用 Clang/GCC 编译)
【发布时间】:2018-04-20 23:49:49
【问题描述】:

我尝试构建一个在 OSX (clang) 和 Linux (GCC/Clang) 上编译得很好的库。我偶然发现了一个 MSVC/Visual Studio 2017 不理解的模板定义。我可以归结为:

#include "stdafx.h"

template<class T>
class Parent {
    class Child {
        friend class Parent;
    public:
        Child(const Child &r);
    };
};

template<class T>
Parent<T>::Child::Child(const Parent<T>::Child &r) {
    *this = r;
}

int main(int argc, char const *argv[]) {
    /* code */
    return 0;
}

这(仍然)会导致以下错误:

1>...consoleapplication1.cpp(13): error C2988: unrecognizable template declaration/definition
1>...consoleapplication1.cpp(13): error C2059: syntax error: '('
1>...consoleapplication1.cpp(13): error C2143: syntax error: missing ';' before '{'
1>...consoleapplication1.cpp(13): error C2447: '{': missing function header (old-style formal list?)

但是(仍然)在 OSX 上使用 Clang 或 GCC 编译。 stdafx.hmain 不是实际库代码的一部分,但已添加以允许在 VS Windows 命令行项目中使用它。

我在这里想念什么? MSVC 是否存在模板中的成员类或友元声明问题?

【问题讨论】:

  • This 解决了这个问题。看起来其中一个肯定是错误的
  • @PasserBy: 将const Parent&lt;T&gt;::Child 更改为const *typename* Parent&lt;T&gt;::Child 确实解决了这个问题。也非常感谢你向我展示了这个非常有用的在线编译器。我一定会用它来解决未来出现的问题。

标签: c++ visual-c++ language-lawyer


【解决方案1】:

VC++ 的问题是参数类型没有被typename 限定。 [temp.res]/7:

[…] 在定义中 declarator-id(关键字)之后的类模板的成员 typename 在引用以前的名称时不需要 声明类型或类的类模板的声明成员 模板。

declarator-iddeclaration 的第一个组件,因此参数子句中的任何成员类型都不需要以 typename 为前缀。

【讨论】:

  • 澄清一下,非尾随返回类型确实需要typename,因为它是declarator-id
  • @PasserBy 是的,这确实有道理,因为我们从左到右解析,所以我们无法更好地了解。
猜你喜欢
  • 1970-01-01
  • 2023-03-21
  • 2014-05-16
  • 2021-03-18
  • 1970-01-01
  • 2020-10-03
  • 2017-10-17
  • 2020-11-13
  • 1970-01-01
相关资源
最近更新 更多