How to detect if a class is final in C++11?

混江龙づ霸主 提交于 2019-12-09 00:22:52

问题


Code first.

#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; 
}

How to implement the class is_final?


回答1:


Type traits are usually implemented using the SFINAE idiom, which places a potentially ill-formed expression inside a function template declaration. Substituting the typename in question into the declaration results in an error, but the error is suppressed in that context, so the declaration is either used or not. But a fallback overload backs up the potentially missing declaration. Another bit of code accesses the function to detect whether the sensitive overload or only the backup was instantiated.

This won't work for final because it can only cause failure during template instantiation of a class. There's no way to overload classes, and no way to tentatively define a class that will fail but not halt compilation in case it's derived from final.

Standard quote, C++11 §14.8.2/8:

Only invalid types and expressions in the immediate context of the function type and its template parameter types can result in a deduction failure. [ Note: The evaluation of the substituted types and expressions can result in side effects such as the instantiation of class template specializations and/or function template specializations, the generation of implicitly-defined functions, etc. Such side effects are not in the “immediate context” and can result in the program being ill-formed. — end note ]




回答2:


As the implementer of GCC's __is_final intrinisic (for PR 51365) I'm pretty sure it can't be done in a library, it needs compiler support.

You can do some very clever things with C++11's SFINAE for expressions feature but to detect whether a class is final you'd need to derive from it, and instantiate the derived type, in a template argument deduction context, but deriving from a class is done in a declaration not an expression.

Also, you should think about whether you only want to know if the final pseudo-keyword was used, or if a class is un-derivable for other reasons, such as having only private constructors.




回答3:


Not sure if this is what you want but you could do something like this:

#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;
}


来源:https://stackoverflow.com/questions/13809359/how-to-detect-if-a-class-is-final-in-c11

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!