Compilation time checks if the base class is an “interface”,

After it turned out that what I originally wanted was probably not possible without C ++ 11, I want to change the requirement a bit and ask you if this is possible.

previous question

Basically I want to check compilation time if the class inherits from the "interface". By interface, I mean a class with only pure virtual methods. I would like to do the following code:

template <typename T> class Impl : public T { public: STATIC_ASSERT_INTERFACE(T); }; 

The behavior here is that if T has only pure virtual methods, then it will compile and if one of its methods does not complete, then it will fail.

Can anyone think of this?

+6
source share
3 answers

It basically looks like Java interfaces . In C ++, there is no interface as such, it's just the terminology used for a class with all purely virtual methods and only static const data members.

In addition, pure virtual methods may or may not have a function body. Thus, pure C ++ virtual methods are not exactly the same as abstract Java methods.

Unfortunately, what you are asking is not possible to simulate in C ++.

+2
source

Firstly, interfaces are not really a native concept for C ++. I am sure that most programmers know what it is, but the compiler does not, and that where you encounter problems. C ++ can do a lot, and I bet you can flip it in the form of many different languages, but if you are going to write C ++, it is best to do something in C ++.

Another thing - there is a lot of gray area. What if you had an “interface” as you expected, but someone did one of them:

 // Technically not a member function, but still changes the behavior of that class. bool operator==(const Interface &left, const Interface &right); 

I am almost 100% sure that you cannot stop someone from doing this.

You may be able to make sure that there are no member variables, although I'm not sure I agree with this path. Make an empty class, and then do static_assert(sizeof(InterfaceClass) == sizeof(Empty)) . I'm not sure if it can be assumed that the size will be 0 - this is a question for someone more familiar with the standards.

+1
source

What you want cannot be done directly, as others have already explained.

However, you can still get the behavior you want with a little discipline from the interface developers. If all of your interfaces are based on a common Interface base class, you can verify that Interface is a base class at compile time using a technique similar to this question .

For instance:

 class Interface { public : virtual ~Interface() { } }; template <typename T> struct IsDerivedFromInterface { static T t(); static char check(const Interface&); static char (&check(...))[2]; enum { valid = (sizeof(check(t())) == 1) }; }; class MyInterface : public Interface { public : virtual void foo() = 0; }; class MyBase { public : virtual void bar() { } }; class Foo : public MyInterface { public : virtual void foo() { } }; BOOST_STATIC_ASSERT(IsDerivedFromInterface<Foo>::valid); // just fine class Bar : public MyBase { public : virtual void bar() { } }; BOOST_STATIC_ASSERT(IsDerivedFromInterface<Bar>::valid); // oops 

Of course, a base class developer can spoof and infer from Interface , although the base class is not an interface. This is why I said that this requires a certain discipline from the developer.

However, I do not see how this will be useful. I never felt that I needed such a compile-time check.

+1
source

Source: https://habr.com/ru/post/911838/


All Articles