我很难构建一个类,它本身包含一个子类,它自己派生自需要来自顶级类的模板参数的类。听起来很可怕,而且在一些MTP建设中确实很深。但是看看我可以从实际代码中缩小的一个简单示例。
我保留原始来源中的姓名。它们在这里并不重要。
template <typename ... T>
class ConstructAll: public T...
{
public:
using ConstructorParms = int;
using BASES_T = ConstructAll<T...>;
ConstructAll(int){}
};
template <typename T>
class WithTemplate
{
};
class WithoutTemplate
{
};
template <typename X>
class CircuitFromNetlist
{
private:
class SerialReader: public ConstructAll<
WithTemplate<X> // use this-> don't compile
//WithoutTemplate // but this works
>
{
public:
SerialReader( typename BASES_T::ConstructorParms p): BASES_T( p ) {}
};
public:
CircuitFromNetlist()
{
SerialReader ser{1};
}
};
int main()
{
CircuitFromNetlist<int> c;
}
如果我使用WithTemplate<X>
它没有编译并遇到:
main.cpp:31:40:错误:'BASES_T'尚未声明 SerialReader(typename BASES_T :: ConstructorParms p):BASES_T(p){} ^ ~~~~~~ main.cpp:在构造函数'CircuitFromNetlist :: SerialReader :: SerialReader(int)'中: main.cpp:31:70:错误:类'CircuitFromNetlist :: SerialReader'没有任何名为'BASES_T'的字段 SerialReader(typename BASES_T :: ConstructorParms p):BASES_T(p){}
如果我将代码翻转为使用非模板化类,它似乎可以工作。
有什么想法让事情发挥作用?
答案 0 :(得分:0)
根据C ++ 11标准,您在这里看到的实际上是正确的行为:
在类或类模板的定义中,如果基类依赖于模板参数,则在非标准名称查找期间不会检查基类范围,或者在定义类模板或成员或在类模板或成员的实例化期间。 - [temp.dep](强调我的)
从ConstructAll<WithoutTemplate>
继承时,基类不依赖于模板参数X
,但显然从ConstructAll<WithTemplate<X>>
继承基类确实依赖于此模板参数。
您必须明确将类型称为typename ConstructAll<WithTemplate<X>>::BASES_T
。