Я хотел бы создать красивый интерфейс на C ++, в котором каждая реализация должна иметь определенное добавление для себя.
Я хотел бы сделать что-то вроде этого:
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.
так как с ++ не принимает контравариантность, моя функция B& operator+(const B& other)
не реализует virtual A& operator+(const A& other)
, Есть ли какой-нибудь хитрый (но немного чистый …) способ сделать это?
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
};
это один из способов. Эта идиома распространена при реализации политики. Увидеть http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
То, что вы пытаетесь сделать, невозможно ни на одном языке, потому что это не имеет смысла.
Это правда, что методы противоречивы в типах аргументов в некоторых языках, но это означает, что метод перегружен, если он принимает супертипом. То есть operator+(const A&)
будет перегружен для operator+(const B&)
, Но не наоборот. Потому что, когда у вас есть два экземпляра (давайте назовем их x
а также y
) и писать x + y
метод будет вызван, и компилятор не может знать, будут ли оба иметь один и тот же подтип, так как эта информация будет доступна только во время выполнения. Так что во время выполнения это единственный раз, когда вы можете проверить это.
Так:
+
в шаблоне, который будет использовать его (он должен быть шаблоном, если он не полиморфный), и компилятор будет суки, когда он не определен. Вы можете написать класс проверки концепции рано обнаруживать и избегать ошибок со слишком глубоким стеком расширения шаблона.