gpt4 book ai didi

c++ - CRTP 和基类定义的类型的可见性

转载 作者:搜寻专家 更新时间:2023-10-31 01:37:29 27 4
gpt4 key购买 nike

这里是一个有效代码的简短示例。它有助于介绍实际问题。
可见性的说明符与实际代码中使用的相同。

class Base {
public:
using foo = int;
virtual ~Base() { }

protected:
static foo bar() noexcept {
static foo v = 0;
return v++;
}
};

template<class Derived>
class Class: public Base {
static foo get() noexcept {
static foo v = bar();
return v;
}
};

int main() { }

它沿用了前面的示例,尽管稍作修改。
模板参数已添加到基类,派生类也已相应更新。
这个不编译。

template<typename T>
class Base {
public:
using foo = int;
virtual ~Base() { }

protected:
static foo bar() noexcept {
static foo v = 0;
return v++;
}
};

template<class Derived, typename T>
class Class: public Base<T> {
static foo get() noexcept {
static foo v = bar();
return v;
}
};

int main() { }

错误确实很明显,问题是没有解决:

main.cpp:18:12: error: ‘foo’ does not name a type
static foo get() noexcept {
^
main.cpp:18:12: note: (perhaps ‘typename BaseComponent<T>::foo’ was intended)

实际问题是:为什么 foo在第二个例子中没有范围说明符是不可见的?
我的意思是,Class源自 Base<T> ,那是(至少在我看来)一个完全定义的类型,因此 foo应该是基类的一部分,因此对派生类可见,就像第一个示例中发生的那样。

它遵循一个例子,根据我对问题的猜测,实际上编译但不应该,或者至少应该像前一个一样:

template <typename T>
struct B {
using foo = T;
};

struct D: public B<int> {
static foo bar;
};

int main() {
B<int> *b = new D;
}

会不会是因为在这种情况下派生类不是模板化类?
老实说,我觉得有点奇怪,因为 foo type 是基类的一部分,它仍然是一个模板化的类,因此它应该与前一个没有太大区别。

不言而喻,我错了,但我想不通我的想法出了什么问题。

提前感谢您的帮助。

最佳答案

那是因为名称查找规则。如果您的基类是模板,则不会解析 base 中的非限定名称。原因是稍后在您的代码中,您可能有该基的模板特化,它没有定义名称,或者名称的含义完全不同。对于编译器来说太复杂了,无法弄清楚你是否有特化,如果有,你的名字在其中的含义是否相同。所以它更愿意推迟名称查找。要让编译器“相信你”,那么你需要使用限定名称,或者使用 this->name(对于成员,而不是 typedef),编译器将解析该名称。

关于c++ - CRTP 和基类定义的类型的可见性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34097810/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com