Reputation: 61
I would like to create a nice interface on C++ on which each implementation needs to have the addition defined, on itself.
I would like to do something like this :
class A{
...
virtual A& operator+(const A& other) =0;
...
}
// this is my interface or abstract class.
class B : A{
...
B& operator+(const B& other);
...
}
// this is the kind of implementation i would like. a B element can be added by another B element only ! At least this the constraint I am aiming at.
as c++ does not accept contravariance, my function B& operator+(const B& other)
does not implement virtual A& operator+(const A& other)
. Is there any tricky (but a little bit clean...) way to do that?
Upvotes: 6
Views: 254
Reputation: 76236
What you are trying to do is not possible in any language, because it does not make sense.
It is true that methods are contravariant in argument types in some languages, but that means that method is an overload if it accepts supertype. I.e. operator+(const A&)
would be overload for operator+(const B&)
. But not the other way around. Because when you have two A instances (let's call them x
and y
) and write x + y
, the method will be called and the compiler can't know whether both will be of the same subtype as that information will only be available at runtime. So at runtime is the only time you can check it.
So:
+
in the template that will be using it (it must be a template if it's not polymorphic) and the compiler will bitch when it's not defined. You may write a concept check class to find out early and avoid errors with too deep template expansion stack.Upvotes: 5
Reputation: 234635
template<class Y>
class A
{
virtual Y& operator+=(const Y& other) = 0;
};
class B : A<B>
{
// must implement B& operator+=(const B& other) else B is abstract
};
is one way. This idiom is common when implementing policies. See http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
Upvotes: 7