C++ 引用基类模板成员变量的简单方法
有没有方法引用基类模板的成员变量而不使用基类名称和范围解析运算符C++ 引用基类模板成员变量的简单方法,c++,templates,base-class,name-lookup,class-template,C++,Templates,Base Class,Name Lookup,Class Template,有没有方法引用基类模板的成员变量而不使用基类名称和范围解析运算符 template<typename D> struct B0 { int value; }; struct D0: B0<D0> { D0() { B0<D0>::value = 1; // OK. value = 1; // OK without `B0<D0>::`. } }; template<ty
template<typename D>
struct B0 {
int value;
};
struct D0: B0<D0> {
D0() {
B0<D0>::value = 1; // OK.
value = 1; // OK without `B0<D0>::`.
}
};
template<typename T>
struct B1 {
T value;
};
template<typename T>
struct D1: B1<T> {
D1() {
B1<T>::value = 1; // OK.
// value = 1; // Compile error without `B1<T>::`.
// Compile error: use of undeclared identifier 'value'
// `B1<T>::` is tedious everywhere `value` is referenced.
}
};
template<typename T, typename D>
struct B2 {
T value;
};
template<typename T>
struct D2: B2<T, D2<T>> { // CRTP
D2() {
B2<T, D2<T>>::value = 1; // OK.
// value = 1; // Compile error without `B2<T, D2<T>>::`.
// Compile error: use of undeclared identifier 'value'
// `B2<T, D2<T>>::` is more tedious for CRTP.
}
};
int main() {
return 0;
}
模板
结构B0{
int值;
};
结构D0:B0{
D0(){
B0::value=1;//确定。
value=1;//不带`B0:::`的情况下可以。
}
};
模板
结构B1{
T值;
};
模板
结构D1:B1{
D1(){
B1::value=1;//确定。
//value=1;//不带'B1:::'的编译错误。
//编译错误:使用未声明的标识符“值”
//`B1:::`在引用`value`的任何地方都很乏味。
}
};
模板
结构B2{
T值;
};
模板
结构D2:B2{//CRTP
D2(){
B2::value=1;//确定。
//value=1;//不带'B2:::'的编译错误。
//编译错误:使用未声明的标识符“值”
//对于CRTP来说,`B2::`更乏味。
}
};
int main(){
返回0;
}
是否可以不写
B1:
或B2:
,这在引用value
的任何地方都很繁琐?作为解决方案,您必须使namevalue
依赖,以使其在名称查找时可见。除了您展示的内容外,您还可以:
使用
介绍名称
template<typename T>
struct D1: B1<T> {
using B1<T>::value; // or move it in method's scope according to your intent
D1() {
value = 1; // OK.
}
};
IIRC,几年前,当Visual C++的模板处理变得更符合标准时,我们不得不对代码库进行一些更改。在此之前,VC++将接受对
值的引用,而不使用this->
。你知道标准中要求使用this->
前缀的动机是什么吗?这显然是多余的?为什么继承成员的查找规则不同于非模板?基类定义就在那里…@Peter,标准说非依赖名称不会在依赖基类中查找。我认为动机是,模板基类可能是专门化的;然后直到实例化,编译器才知道数据成员是否存在于基中。然后我们必须使名称依赖,这将只在实例化时查找,届时将知道必须探索的确切基础专门化。感谢您的快速回复。我知道猜测动机通常是徒劳的,但是:添加this->
如何改变关于未知基类专门化的任何事情?当然,它可能会显示编码者的意图,实际上是说“我非常确定该成员将在那里”,就像一个cast显示意图一样。@Peter,因为添加this->
使其明确名称是类的数据成员,这取决于模板参数,然后必须在实例化时查找名称。否则,名称可能是其他名称,如全局变量;即使没有资格,也应该找到它,并且工作良好。编译器只是在第一次抱怨,它不会在实例化时再次尝试,它可能太复杂了。
template<typename T>
struct D1: B1<T> {
D1() {
this->value = 1; // OK.
}
};