C++ CRTP和由基类定义的类型的可见性
下面是一个简单的代码示例。它有助于介绍实际问题。C++ CRTP和由基类定义的类型的可见性,c++,templates,visibility,crtp,C++,Templates,Visibility,Crtp,下面是一个简单的代码示例。它有助于介绍实际问题。 可见性的说明符与实际代码中使用的相同。 class Base { public: using foo = int; virtual ~Base() { } protected: static foo bar() noexcept { static foo v = 0; return v++; } }; template<class Derived> class Cla
可见性的说明符与实际代码中使用的相同。
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() { }
在这种情况下,可能是因为派生类不是模板类吗?老实说,我觉得这有点奇怪,因为
foo
类型是基类的一部分,基类仍然是模板类,所以它应该与前一个没有太大区别
不言而喻,我错了,但我无法找出我思想中的错误。提前感谢您的帮助。这是因为名称查找规则。如果基类是模板,则不会解析基类中的非限定名称。原因是,在代码的后面部分,您可能会有一个没有定义名称的基模板专门化,或者名称的含义完全不同。编译器很难判断您是否有专门化,如果有,您的名字在其中是否意味着相同的东西。因此,它倾向于推迟名称查找。要使编译器“相信你”,那么你需要使用一个限定名,或者改用
this->name
(对于成员,而不是typedef),编译器将解析名称。this->foo有意义吗??O.O请注意,foo
是一个类型,而不是数据成员。@skypjack我进行了编辑。您对成员使用this->member
,而不是对typedef。但答案中所述的理由是站得住脚的。编译器很难判断您是否有专门化,如果有,您的名字在其中是否意味着相同的东西。所以它更倾向于推迟名称查找。你要告诉我一些以前从未听说过的关于别名的this->foo
语法!!:-)。。。我将用另一个例子来更新这个问题,但我仍然无法用这种方式解释。在您的上一个例子中,Base不再是依赖类型,编译器可以完全解决它。@skypjack Done。它在C++中具有名称查找规则的意义。顺便说一句,我从网上了解到了这些问题。这是一本好书。
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)
template <typename T>
struct B {
using foo = T;
};
struct D: public B<int> {
static foo bar;
};
int main() {
B<int> *b = new D;
}