After it turned out that what I originally wanted is probably not possible w/o involving C++11 I want to slightly change the requirement and ask you if this can be achieved.
previous question
Basically I want to check in compile time if a class is inheriting from "interface". By interface I mean class with pure virtual methods only. I would like to do the following code:
template <typename T>
class Impl : public T {
public:
STATIC_ASSERT_INTERFACE(T);
};
The behavior here is if T has only pure virtual methods then it will compile and if one of its methods is not then fail.
Can anyone think of something like that?
This is basically similar to Java interfaces. In C++, there is no existence of interface
as such, it's just a terminology used for a class
with all pure-virtual methods and only static const
data members.
Additionally, pure virtual methods may or may not have a function body. Thus C++ pure virtual methods are not exactly same as Java's abstract methods.
Unfortunately what you are asking is not possible to simulate in C++.
First off, interfaces are not really a native concept to C++. I'm sure most programmers know what they are, but the compiler doesn't, and that's where you're running into problems. C++ can do a lot of things, and I bet you can twist it into looking like a lot of different languages, but if you're going to write C++, it's best to do things the C++ way.
Another thing - there's a lot of grey area here. What if you had an "interface" like you suggested, but somebody did one of these:
// Technically not a member function, but still changes the behavior of that class.
bool operator==(const Interface &left, const Interface &right);
I'm almost 100% sure you can't stop someone from doing that.
You may be able to make sure there are no member variables though, even though I'm not sure I agree with this way of doing things. Make an empty class, and then do a static_assert(sizeof(InterfaceClass) == sizeof(Empty))
. I'm not sure if it's safe to assume the size would be 0 - that's a question for someone more familiar with the standards.
What you want can not be done directly, as others have already explained.
However, you can still get the behavior you want with a bit of discipline from the interface developers. If all your interfaces derive from a common base class Interface
, you can check that Interface
is a base class at compile time using a technique similar to this question.
For example :
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, the developer of the base class can cheat and derive from Interface
even though the base class is not an interface. Which is why I said it requires some discipline from the developer.
That said though, I can't see how this would be useful. I've never felt I needed this kind of compile time check.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With