Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting if a type can be derived from in C++

I have the following template class and a (global) variable of its type:

template <typename ClassT>
struct ClassTester : public ClassT {
    typedef ClassT type;
};

ClassTester<int> *aaa;  // No error here

I would expect a compilation error because int cannot be derived from, but this compiles fine under Visual C++ 2010.

If I remove the pointer, I get the expected compilation error (int cannot be derived from):

ClassTester<int> bbb; // Error here

I wanted to use this class for SFINAE testing whether the given type is a class that can be derived from:

template <typename T>
struct CanBeDerivedFrom  {

    template <typename C>
    static int test(ClassTester<T> *) { }

    template <typename>
    static char test(...) { }

    static const bool value = (sizeof(test<T>(0)) == sizeof(int));
};

This, however, always reports true, even for primitive types such as int because of the above reason. Is this an expected/valid behavior of C++?

like image 321
Karel Petranek Avatar asked Dec 06 '11 09:12

Karel Petranek


2 Answers

Do not reinvent the wheel. Use boost::is_class boost reference manual

Those guys known better than you do.

like image 175
reder Avatar answered Oct 22 '22 10:10

reder


Unfortunately I think that this is actually impossible.

Many issues may prevent derivation (or at least, useful derivation), the addition of final to the standard being one.

For example, see this thread on the Clang mailing list where Howard Hinnant requires a compiler intrinsic to check whether the class is marked as final or not.

like image 34
Matthieu M. Avatar answered Oct 22 '22 10:10

Matthieu M.