C++ 如何检测C+中的类是否为final+;11?
先编码C++ 如何检测C+中的类是否为final+;11?,c++,c++11,final,typetraits,C++,C++11,Final,Typetraits,先编码 #include <iostream> using namespace std; struct A final {}; struct B {}; int main() { cout << is_final<A>::value << endl; // Output true cout << is_final<B>::value << endl; // Output false
#include <iostream>
using namespace std;
struct A final {};
struct B {};
int main()
{
cout << is_final<A>::value << endl; // Output true
cout << is_final<B>::value << endl; // Output false
return 0;
}
#包括
使用名称空间std;
构造一个最终的{};
结构B{};
int main()
{
不能确定这是否是您想要的,但您可以这样做:
#include <iostream>
struct Foo {};
struct Bar {};
template<typename T>
struct is_final {
static const bool value = false;
};
template<>
struct is_final<Bar> {
static const bool value = true;
};
int main(void) {
std::cout << is_final<Foo>::value << std::endl;
std::cout << is_final<Bar>::value << std::endl;
}
#包括
结构Foo{};
结构条{};
模板
结构是最终的{
静态常量布尔值=假;
};
模板
结构是最终的{
静态常量布尔值=真;
};
内部主(空){
std::cout作为GCC的\uu的实现者是最终的intrinisic(for),我非常确定它不能在库中完成,它需要编译器支持
使用C++11的SFINAE for expressions功能可以做一些非常聪明的事情,但要检测类是否为final,您需要在模板参数推导上下文中从它派生并实例化派生类型,但从类派生是在声明而不是表达式中完成的
此外,您应该考虑是否只想知道是否使用了final
伪关键字,或者是否因为其他原因(例如只有私有构造函数)类不可派生。类型特征通常使用SFINAE习惯用法实现,这会在函数模板中放置一个可能格式错误的表达式laration。将相关的typename替换到声明中会导致错误,但该错误在该上下文中被抑制,因此该声明要么被使用,要么不被使用。但回退重载会备份可能丢失的声明。另一位代码访问该函数以检测敏感重载还是仅备份已实例化
这对final
不起作用,因为它只能在类的模板实例化过程中导致失败。无法重载类,也无法暂时定义一个类,如果它是从final派生的,它将失败但不会停止编译
标准引用,C++11§14.8.2/8:
只有函数类型及其模板参数类型的直接上下文中的无效类型和表达式才能导致推断失败。[注:对替换类型和表达式的求值可能会产生副作用,如类模板专门化和/或函数模板专门化的实例化、隐式定义函数的生成等。此类副作用不在“即时上下文”中并可能导致程序格式错误。-结束注释]
疯狂猜测:这是不可能的。C++类型的系统不维护一个给定类的子类的可遍历链接,只是通过继承链来绕过。你到底想要实现什么?(仍然是1,有趣,简洁地提出问题)。我不确定是否有可能触发一个SFINAE条件,让您对此进行测试。我知道G++实现了一个_is_final关键字,但这就是我所发现的。它依赖于实现,但在有限的情况下可以实现。我认为没有编译器支持也不可能。可能值得添加std::is_final代码>。我想使用宏将冗长的代码插入到类中,但代码要求该类不能被继承。因此,我想添加静态\u断言(is\u final::value,“宏不能插入到非final类中”);在宏体内部。更新:std::final
在C++14中。我想你误解了这个问题。我明白,如果不指定类是否为final,你就不能这样做。@gvdfinal
是一个(新的,上下文条件的)可以应用于类声明的关键字。他希望检测是否使用了该关键字。如果将其作为标准考虑,则可能需要两个建议-是final
和是可派生的
,这两个建议都实现了不同的语义。尽管在TMP中,拥有私有构造函数并不妨碍正常的派生永远不要构造这样的类型。@Xeo是可派生的
对于可访问构造函数的测试来说是一个误称,因为你仍然可以派生和使用一个没有构造函数的非静态成员的类……呃,我的意思是你可以使用静态成员。我想委员会宁愿投票支持final(classOrMethod)
和重写(classOrMethod)
或类似的方法,只是重复使用现有的关键字,而不是引入新的关键字。更晚的是(C++14)std::is_final
被添加,这很可能使用了编译器的固有特性