![](/img/trans.png)
[英]Using typedefs of a non-template derived class in the base class when using CRTP
[英]Use of derived class' typedefs in base
我希望派生类是模板类的后代。 那个班级取决于后代的成员。 总之,我希望这段代码能够编译:
struct IBootParams
{
virtual bool GetImmediate() = 0;
};
template <class T>
struct TBootBootParams
{
typename T::TransType transferType;
typename T::UseAbort_ useAbort;
bool GetImmediate()
{
if ( transferType == T::e1 )
{
return useAbort.someFlag;
}
return false;
}
};
struct BootBootParams : public TBootBootParams<BootBootParams>
{
enum SomeEnum
{
e1=0,
e2,
e3
};
struct UseAbort
{
bool someFlag;
char someMember;
int otherMember;
} useAbort;
typedef SomeEnum TransType;
typedef UseAbort UseAbort_;
};
struct BootAltBootParams : public TBootBootParams<BootAltBootParams>
{
enum SomeEnum
{
e1=5,
e2,
e3
};
struct UseAbort
{
bool someFlag;
long long someMember;
long long otherMember;
} useAbort;
typedef SomeEnum TransType;
typedef UseAbort UseAbort_;
};
int _tmain(int argc, _TCHAR* argv[])
{
BootBootParams bp;
BootAltBootParams bpa;
bool f = bp.GetImmediate();
f = bpa.GetImmediate();
}
你不能这样做。 当编译器实例化TBootBootParams<BootBootParams>
它尚未完全读取BootBootParams的整个定义,因此您无法从TBootBootParams的定义内部访问其成员(TBootBootParams的成员函数是一个例外,因为它们稍后被实例化)。
通常的解决方案是有一个特质类:
template<class T> struct TBootBootParams_traits;
template <class T>
struct TBootBootParams
{
typename TBootBootParams_traits<T>::TransType transferType;
typename TBootBootParams_traits<T>::UseAbort_ useAbort;
bool GetImmediate()
{
if ( transferType == TBootBootParams_traits<T>::e1 )
{
return useAbort.someFlag;
}
return false;
}
};
struct BootBootParams;
template<> struct TBootBootParams_traits<BootBootParams>
{
enum SomeEnum
{
e1=5,
e2,
e3
};
struct UseAbort
{
bool someFlag;
long long someMember;
long long otherMember;
};
typedef SomeEnum TransType;
typedef UseAbort UseAbort_;
};
struct BootBootParams :
public TBootBootParams<BootBootParams>,
public TBootBootParams_traits<BootBootParams>
{
UseAbort_ useAbort;
};
没有办法可以解决这个问题。 所以这是我尝试的一点点黑客攻击:
struct IBootParams
{
virtual bool GetImmediate() = 0;
};
template <class T>
struct TBootBootParams : public IBootParams
{
typename T::TransType transferType;
typename T::UseAbort_ useAbort;
virtual bool GetImmediate()
{
if ( transferType == T::e1 )
{
return useAbort.someFlag;
}
return false;
}
};
struct BootBootParams_types
{
enum SomeEnum
{
e1=0,
e2,
e3
};
struct UseAbort
{
bool someFlag;
char someMember;
int otherMember;
} useAbort;
typedef SomeEnum TransType;
typedef UseAbort UseAbort_;
};
struct BootBootParams : public BootBootParams_types,
public TBootBootParams<BootBootParams_types>
{
};
struct BootAltBootParams_types
{
enum SomeEnum
{
e1=5,
e2,
e3
};
struct UseAbort
{
bool someFlag;
long long someMember;
long long otherMember;
} useAbort;
typedef SomeEnum TransType;
typedef UseAbort UseAbort_;
};
struct BootAltBootParams : public BootAltBootParams_types,
public TBootBootParams<BootAltBootParams_types>
{
};
int main(int argc, const char * argv[])
{
BootBootParams bp;
BootAltBootParams bpa;
bool f = bp.GetImmediate();
f = bpa.GetImmediate();
}
这样做你想要的吗? 它汇编。
struct IBootParams
{
virtual bool GetImmediate() = 0;
};
template <class T>
struct TBootBootParams
{
bool GetImmediate()
{
if ( static_cast<T*>(this)->transferType == T::e1 )
{
return static_cast<T*>(this)->useAbort.someFlag;
}
return false;
}
};
struct BootBootParams : public TBootBootParams<BootBootParams>
{
enum SomeEnum
{
e1=0,
e2,
e3
} transferType;
struct UseAbort
{
bool someFlag;
char someMember;
int otherMember;
} useAbort;
};
struct BootAltBootParams : public TBootBootParams<BootAltBootParams>
{
enum SomeEnum
{
e1=5,
e2,
e3
} transferType;
struct UseAbort
{
bool someFlag;
long long someMember;
long long otherMember;
} useAbort;
};
int main(void)
{
BootBootParams bp;
BootAltBootParams bpa;
bool f = bp.GetImmediate();
f = bpa.GetImmediate();
}
我尝试了一些改变ybungalobill的解决方案,计算我自己的需求。 这就是我得到的
template<class T>
struct TBootBootParams_traits;
template <class T>
struct TBootBootParams
{
typedef TBootBootParams_traits<T> Traits;
typename Traits::TransType transferType;
typename Traits::UseAbort_ useAbort;
bool GetImmediate()
{
if ( transferType == TBootBootParams_traits<T>::e1 )
{
return useAbort.someFlag;
}
return false;
}
};
struct BootBootParams;
struct BootAltBootParams;
template<>
struct TBootBootParams_traits<BootBootParams>
{
enum SomeEnum
{
e1=5,
e2,
e3
};
struct UseAbort
{
bool someFlag;
long long someMember;
long long otherMember;
};
typedef SomeEnum TransType;
typedef UseAbort UseAbort_;
};
template<>
struct TBootBootParams_traits<BootAltBootParams>
{
enum SomeEnum
{
e1=5,
e2,
e3
};
struct UseAbort
{
bool someFlag;
int someMember;
float otherMember;
};
typedef SomeEnum TransType;
typedef UseAbort UseAbort_;
};
struct BootBootParams :
public TBootBootParams<BootBootParams>
{
};
struct BootAltBootParams :
public TBootBootParams<BootAltBootParams>
{
};
int main(void)
{
BootBootParams bp;
BootAltBootParams bpa;
bool f = bp.GetImmediate();
f = bpa.GetImmediate();
}
总结一下..我使用模板类作为此类的另一个类的必备选项,将所有类型数据放在那里。 这正是我所需要的。 再次感谢您的选择!
要使此方法起作用,必须将模板类对象包含为父类的成员。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.