【问题标题】:a call to a method from base template fails to compile [duplicate]从基本模板调用方法无法编译[重复]
【发布时间】:2020-08-13 09:17:48
【问题描述】:

我有一个模板结构,它继承了另一个模板结构。它在不同的编译器中编译失败(在 VS2017 和 linux 上的 clang)。对代码进行简单的更改即可修复它。 代码是:

template<typename T>
struct base {
    int GetValue2() { return 0; }
};

template<typename T>
struct derived : public base<T>
{
    int GetValue() { return GetValue2(); }
};

int main() {
    derived<int> a;

    return 1;
}

如果我换行 int GetValue() { return GetValue2(); } 到: int GetValue() { return this->GetValue2(); } 一切都编译得很好。

有人知道发生了什么吗?

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    这里有一个两阶段的名称查找。

    在 GetValue() 中,GetValue2 不在依赖上下文中使用,因此编译器将查找在封闭命名空间范围(此处为全局范围)声明的名称。

    它不会查看基类,因为它是依赖的,即使在声明了 Derived 之后,您也可以声明 Base 的特化,因此编译器无法真正知道我将指代什么。如果没有全局变量 i,则会收到错误消息。

    为了清楚地表明您想要基类的成员,您需要将查找推迟到实例化时间,此时基类是已知的。为此,您需要在依赖上下文中访问 i,方法是使用 this->i(记住 this 是 Derived* 类型,因此显然是依赖的),或者使用 Base::i。或者,Base::i 可能会被 using 声明纳入范围。

    template<typename T>
    struct base {
        int GetValue2() { return 0; }
    };
    
    template<typename T>
    struct derived : public base<T>
    {
        int GetValue_using() { 
            using base<T>::GetValue2; // won't compile with gcc, place it outside the function (ok with clang and msvc)
            return GetValue2(); 
        }
        int GetValue_this() { return this->GetValue2(); }
        int GetValue_base() { return base<T>::GetValue2(); }
    };
    
    int main() {
        derived<int> a;
        return 1;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-07
      • 1970-01-01
      • 2019-05-29
      • 1970-01-01
      • 2016-08-17
      • 1970-01-01
      相关资源
      最近更新 更多