【问题标题】:Different behavior between g++ and clang++ in nested classes嵌套类中 g++ 和 clang++ 之间的不同行为
【发布时间】:2020-02-09 17:04:19
【问题描述】:

我注意到gcc 9.2.0 和clang++ 9.0.1 之间的行为不同。我的代码如下

//header.hh
     ...
template <typename T>
class Outer {
     ...
  public:
     template <typename S>
     class Inner;
     ... 
};

template <typename T>
template <typename S>
class Inner {
     ...
      Inner& func();
     ...
};

那么,由于函数func()是在另一个文件中实现的

//implementation.cc
template <typename T>
template <typename S>
Outer<T>::Inner<S>& Outer<T>::Inner<S>::func() {
    ...
};

现在,如果我使用g++,编译就可以了。如果我使用clang++ 我会得到

src/implementation.cc:6:1: error: missing 'typename' prior to dependent type template name 'Outer<T>::Inner'
Outer<T>::Inner<S>& Outer<T>::Inner<S>::func() {
^
1 error generated.

但是,如果我按照它的建议使用

typename Outer<T>::Inner<S>& Outer<T>::Inner<S>::func()

我又遇到了一个错误:

src/implementation.cc:6:21: error: use 'template' keyword to treat 'Inner' as
a dependent template name typename Outer<T>::Inner<S>& Outer<T>
::Inner<S>::func() {

现在它的建议似乎很奇怪。

问题

  1. 为什么两个编译器的行为不同?
  2. 使用的正确语法是什么?

【问题讨论】:

  • 你有一个更大的问题要担心。即使在您解决编译错误之后,尽管您的问题提供的信息有限,但您的程序似乎很可能无法通过任一编译器链接,因为模板只能在头文件中实现。您在名为“implementation.cc”的东西中定义模板的尝试注定要彻底失败。 C++ 根本无法以这种方式工作。
  • 能否请您更新您的示例,它们与错误消息不一致(例如 Inner-Outer order、Iterator 类)。
  • 同样,你需要edit你的问题只包含一个代码sn-p来演示你所询问的编译错误。
  • 我编辑了这个问题。不过我很抱歉我的无知。我只是不知道不能将模板的定义与声明分开。
  • 您的问题仍然缺少minimal reproducible example。您可以剪切/粘贴您的问题中的内容,并重现您的编译错误吗?显然不是,直到它是,它不是定义上的minimal reproducible example。获得此类帮助的最佳方式是让其他人尽可能轻松地重现您的错误。

标签: c++ gcc c++17 clang++


【解决方案1】:

正确的语法如下:

template <typename T>
template <typename S>
typename Outer<T>::template Inner<S> &Outer<T>::Inner<S>::func() {
    ...
}

您可以在this 问题中找到此语法的完整说明。

但是,更简单且有效的语法是这样的:

template <typename T>
template <typename S>
auto Outer<T>::Inner<S>::func() -> Inner& {
    ...
}

通过在上例中使用尾随返回类型语法,您可以利用名称解析范围在 Outer&lt;T&gt;::Inner&lt;S&gt; 内这一事实,因此您可以使用 Innerinjected class name

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-22
    • 1970-01-01
    • 1970-01-01
    • 2016-06-19
    • 1970-01-01
    • 2018-01-06
    • 2017-02-22
    相关资源
    最近更新 更多