[英]Template class does not see inherited template member
Let me consider a template class which derived from a base template class. 让我考虑一个从基本模板类派生的模板类。 The base class contains a template member.
基类包含模板成员。 In this case, usually members of the base class can be accessed from the derived class using the pointer
this
. 在这种情况下,通常可以使用指针
this
从派生类访问基类的成员。 It appears however that this is not the case, when a base member is itself a template function. 然而,当基础成员本身是模板功能时,似乎不是这种情况。
Consider the following code 请考虑以下代码
#include <iostream>
template <class T>
struct base {
T x;
base() { x = 10; }
template <unsigned int N>
void increment() { x += N; }
};
template <class T>
struct deriv : public base<T> {
using base<T>::base;
void p()
{
using namespace std;
cout << this->x << endl;
base<int>::increment<1>();
// The following statement causes the compile error:
// expected primary-expression before ‘)’ token
// this->increment<1>();
// Also the following statement gives error
// base<T>::increment<1>();
cout << this->x << endl;
}
};
int main()
{
using namespace std;
base<int> A;
cout << A.x << endl;
A.increment<1>();
cout << A.x << endl;
deriv<int> B;
B.p();
return 0;
}
In the main
routine the template member increment
is called from a variable of type base
. 在
main
例程中,从类型为base
的变量调用模板成员increment
。 This works without any problem. 这没有任何问题。 On the other hand, the member function
p()
of the deriv
class tries to access to the template function increment
inherited from base. 另一方面,
deriv
类的成员函数p()
尝试访问从base继承的模板函数increment
。 Using the pointer this
as in the commented line above 使用指针
this
如在上面的注释行
this->increment<1>();
gives the compile error 给出了编译错误
expected primary-expression before ‘)’ token
After trying for a while, I found it possible, as in the code above, to access to the increment
function via the scope operator 在尝试了一段时间后,我发现可以通过范围运算符访问
increment
函数,如上面的代码所示
base<int>::increment<1>();
This however explicitly instantiate base
with T=int
. 然而,这显然是用
T=int
实例化base
。 If I want to call the increment
member from the inherited base<T>
, with generic T
class as 如果我想从继承的
base<T>
调用increment
成员,使用泛型T
类
base<T>::increment<1>();
I get the same error as above. 我得到与上面相同的错误。
I am using gcc 8.1.1 我正在使用gcc 8.1.1
The question is: why using the pointer this
cannot the compiler resolve the inherited member function increment
? 问题是:为什么使用指针
this
不能编译器解析继承的成员函数increment
? How can I get instantiate the inherited template function increment
, from the inherited class base
? 我怎样才能获得实例继承模板函数
increment
,从继承的类base
?
Edit: I added another case where it fails to compile, better specify the question. 编辑:我添加了另一个无法编译的情况,更好地指定问题。
Edit: small correction in the program, same question. 编辑:程序中的小修正,同样的问题。
Unless you specify otherwise, the compiler assumes that the name you access is not a template, so both <
and >
are tokenized as less than and greater than signs respectively (the line is parsed as ((this->increment)<1)>()
). 除非您另行指定,否则编译器会假定您访问的名称不是模板,因此
<
和>
分别被标记为小于和大于符号(该行被解析为((this->increment)<1)>()
)。 This happens because this
and base<T>
are both dependent on the template parameter T
and the compiler cannot look up increment
to see if it is a template. 发生这种情况是因为
this
和base<T>
都依赖于模板参数T
,并且编译器无法查找increment
以查看它是否是模板。 This holds for any case where the name on the left of an operator is dependent on any template parameter and the name on the right is template-id (name with <>
). 这适用于任何情况,其中运算符左侧的名称依赖于任何模板参数,右侧的名称是template-id(名称带有
<>
)。 To solve this problem, you need to use the template
keyword 要解决此问题,您需要使用
template
关键字
base<T>::template increment<1>();
this->template increment<1>();
Why does base<int>::increment<1>();
为什么
base<int>::increment<1>();
compile then? 然后编译? Because it does not depend on
T
(refers to a known specialization), thus the name increment
can be looked up to determine whether it is or is not a template. 因为它不依赖于
T
(指的是已知的特化),所以可以查找名称increment
以确定它是否是模板。
But it won't compile if T
is not int
. 但如果
T
不是int
,它将无法编译。 gcc gives the following error gcc给出以下错误
[x86-64 gcc 8.1 #1] error: type 'base<int>' is not a base type for type 'deriv<long long int>'
If base<int>::increment
was public static, the code would always compile (not exactly because the compiler would compile about x
not being static, but with additional changes it would). 如果
base<int>::increment
是public static,那么代码总是会编译(不完全是因为编译器会编译x
不是静态的,但会有额外的更改)。
Calling this->increment<1>()
is invalid because increment
is a dependent function template. 调用
this->increment<1>()
无效,因为increment
是依赖函数模板。 You need therefore need to use the template
keyword: 因此,您需要使用
template
关键字:
this->template increment<1>();
Your using
directive and base<int>::increment<1>()
call are also not correct. 您的
using
指令和base<int>::increment<1>()
调用也不正确。 If deriv
is intantiated with a type other than int
neither of those will work. 如果
deriv
是intantiated比其他类型int
那些都将工作。 You should use T
instead of int
in both of those. 你应该在这两个中使用
T
而不是int
。 When doing so the call to base<T>::increment<1>()
will become invalid for the same reason this->increment<1>()
is invalid. 执行此操作时,对
base<T>::increment<1>()
的调用将因同一原因this->increment<1>()
无效而变为无效。 You need the template
keyword there as well: 那里你也需要
template
关键字:
base<T>::template increment<1>();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.