[英]Accessing inherited objects from class template
I've been learning C++ templating and I've run across some weird behavior. 我一直在学习C ++模板,我遇到了一些奇怪的行为。 Consider this class structure (stripped down from my original code):
考虑这个类结构(从我的原始代码中删除):
class A {
public:
std::vector <int> vec;
};
template <typename T> class B : public A { };
template <typename T> class C : public B<T> {
public:
using A::vec;
int test() {
return vec[1]; // OK
}
int test2() {
return vec.size(); // error: 'class A' has no member named 'size'
}
};
When compiling, I get an error in test2
, saying that class A
has no member size
. 编译时,我在
test2
得到一个错误,说class A
没有成员size
。 But vec
should be a vector
object, not an instance of A
. 但是
vec
应该是一个vector
对象,而不是A
的实例。 Indeed, if I derive C
directly from A
instead of B<T>
, or remove the template from C
, it compiles fine. 实际上,如果我直接从
A
而不是B<T>
派生C
,或者从C
删除模板,那么它编译得很好。
Furthermore, if I add the following method to C
: 此外,如果我将以下方法添加到
C
:
int test3() {
void ***v = vec; // error: cannot convert from
// 'std::vector<int,...>' to 'void***'
}
the compiler says it can't convert from a vector<int>
to void***
, so it seems to know the correct type for vec
. 编译器说它无法从
vector<int>
转换为void***
,因此它似乎知道vec
的正确类型。 Am I making a mistake here, or is this possibly a bug in my compiler? 我在这里犯了错误,或者这可能是我的编译器中的错误? I'm using an Apple version of g++ 4.2.1.
我正在使用Apple版的g ++ 4.2.1。 Edit: also seems to occur in later versions of g++.
编辑:似乎也出现在g ++的更高版本中。
Thanks for your help! 谢谢你的帮助!
Second edit : my compiler is happy if I use this->vec.size()
in test2
instead of relying on the using A::vec
declaration. 第二次编辑 :如果我在
test2
使用this->vec.size()
而不是依赖于using A::vec
声明,我的编译器很高兴。
First, your code compiles with clang (see it here ), and doesn't compile with gcc . 首先,你的代码用clang编译( 在这里看到),不用gcc编译。 I also got it to compile with VS2013.
我也用VS2013编译它。
Your original issue is related to how the compiler lookup names in templates. 您的原始问题与编译器在模板中查找名称的方式有关。
The Standard § 14.6.2 : 标准§14.6.2:
Non-dependent names used in a template definition are found using the usual name lookup and bound at the point they are used.
模板定义中使用的非依赖名称可以使用通常的名称查找找到,并在使用它们时绑定。
Also the C++ FAQ has a good entry about it : 此外, C ++ FAQ有一个很好的条目:
The compiler does not look in dependent base classes (like B) when looking up nondependent names (like vec).
查找非依赖名称(如vec)时,编译器不会查找依赖的基类(如B)。
Solution : 方案 :
1. Use this->vec
(this is always implicitly dependent in a template) 1.使用
this->vec
(这总是隐含地依赖于模板)
int test2() {
return this->vec.size();
}
2. Use using B<T>::vec
2.使用
using B<T>::vec
3. Use B<T>
directly : 3.直接使用
B<T>
:
int test2() {
return B<T>::vec.size();
}
Notes: 笔记:
using A::vec;
using A::vec;
, looks like a compiler bug to me (and note that using B<T>::A::vec;
works). using B<T>::A::vec;
工作)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.