C++ 用C++;17是否可以检测结构/类是否有任何基?
我需要一个类型特征,如果给定的类型派生自任何东西,则该特征为true,否则为false 例如:C++ 用C++;17是否可以检测结构/类是否有任何基?,c++,inheritance,c++17,typetraits,C++,Inheritance,C++17,Typetraits,我需要一个类型特征,如果给定的类型派生自任何东西,则该特征为true,否则为false 例如: template<class T> struct is_inherit //... logic of inheritance detection ; template<class T> void AppLogic(){ if constexpr(is_inherit<T>::value) { puts("T has base
template<class T>
struct is_inherit
//... logic of inheritance detection
;
template<class T>
void AppLogic(){
if constexpr(is_inherit<T>::value) {
puts("T has base");
//...
} else {
puts("T doesn't have base");
//...
}
}
struct A {};
struct C {};
struct B: C {};
int main() {
AppLogic<A>(); // print: T doesn't have base
AppLogic<B>(); // print: T has base
}
模板
结构是继承的
//... 继承检测逻辑
;
模板
void AppLogic(){
if constexpr(is_inherit::value){
看跌期权(“T有基数”);
//...
}否则{
看跌期权(“T没有基础”);
//...
}
}
结构A{};
结构C{};
结构B:C{};
int main(){
AppLogic文档,如果是类型:
- 具有1、2、4、8、16、32或64位的长度
- 没有用户定义的构造函数、析构函数或复制赋值运算符
- 没有私有或受保护的非静态数据成员
- 没有引用类型的非静态数据成员
- 没有基类
- 没有虚拟功能
- 并且没有不符合这些要求的数据成员
然后它的返回值在RAX寄存器中,否则函数
有一个隐藏的参数,我必须检测和处理
这曾经是C++03 POD的定义,但在C++11中,这发生了变化:
由于C++11标准中的定义已更改,因此我们不建议在此测试中使用std::is_pod
到目前为止,通过一些共轭特征,我可以检测类型是否符合C++03 POD的定义。但是,使用C++17,聚合规则发生了变化,这打破了我的解决方案
如果我能以某种方式检测到一个类型T是否有任何基类,我的解决方案将再次起作用。我相信检查“T
是否派生自任何东西”这是不可能的,至少不是以标准兼容的方式。如果您使用此技术检查类型是否为POD/平凡/聚合,则有一些类型特征可能会帮助您:
是的,这是可能的,至少对于骨料而言是可能的
首先,我们构造一个可转换为其模板参数的任何适当基的类模板:
template<class T>
struct any_base {
operator T() = delete;
template<class U, class = std::enable_if_t<std::is_base_of_v<U, T>>> operator U();
};
.如果它有一个基本的基础?不要认为你能做到这一点而不“作弊”你需要等内省,把它添加到C++中,或者找到一个编译器特有的技巧。否则,我认为你不能做它。但是,正如Vittorio Romeo所建议的,这可能是XY问题。为什么你需要这个?也许有更好的方法来解决你原来的问题。我们知道你试图解决的问题,我们可能会提供可行的替代方案,事实上,即使你能做你想做的事,这可能是更好的解决方案。或者这是一个哲学问题吗?有两件事情很接近,std::is_minole
,或者std::is_aggregate
。但问题到底是什么你是在试图解决这个问题吗?不,不是关于确定一个类是否有基类的问题。但是无论你认为解决方案涉及到什么问题,都需要确定一个类是否有基类。std::你不是在追求什么吗?真的吗?为什么基类很重要,只要它与任何C数据类型兼容?std::若我有一个像classe{E(B&){}这样的类,那个么它是基吗
我担心你会说什么true@gu1d0哦,是的,我忘记了std::is_base_of
说类是它自己的基。修复为只允许正确的基。谢谢!@gu1d0是的,但是如果E有任何构造函数,那么它就不是微不足道的,因此不是聚合的。ecatmur编写了这个解决方案“至少对于聚合是有效的”。这将是我的C++03 POD检测特性的一部分,因此这个解决方案对我来说就足够了。模板结构是_cpp03_POD:std::bool_constant{};
至少对于聚合而言……其中第一个基类之后的所有子对象都是默认可构造的:)@Nyufu结构D{B;};
?
template<class, class = void> struct has_any_base : std::false_type {};
template<class T>
struct has_any_base<T, std::void_t<decltype(T{any_base<T>{}})>> : std::true_type {};