В последнее время я много программировал на Java, сейчас возвращаюсь к своим корням в C++ (мне реально стало не хватать указателей и ошибок сегментации). Зная, что C++ имеет широкую поддержку шаблонов, мне было интересно, есть ли в нем некоторые возможности Java, которые могли бы быть полезны для написания обобщенного кода. Допустим, у меня есть две группы классов. У одного из них метод first()
, у другого метод second()
. Есть ли способ специализации шаблонов, которые будут выбираться компилятором, в зависимости от методов, которыми обладает один класс? Я стремлюсь к поведению, похожему на поведение Java:
public class Main {
public static void main(String[] args) {
First first = () -> System.out.println("first");
Second second = () -> System.out.println("second");
method(first);
method(second);
}
static <T extends First> void method(T argument) {
argument.first();
}
static <T extends Second> void method(T argument) {
argument.second();
}
}
Где First
и Second
— это интерфейсы. Я знаю, что могу сгруппировать обе эти группы, производя каждую из них от высшего класса, но это не всегда возможно (автобоксинг в C++ отсутствует, а некоторые классы не наследуются от общего предка).
Хорошим примером моих потребностей является библиотека STL, в которой некоторые классы имеют такие методы, как push()
, а некоторые другие — insert()
или push_back()
. Допустим, я хочу создать функцию, которая должна вставлять несколько значений в контейнер, используя функцию с переменным числом аргументов. В Java это легко сделать, потому что у коллекций есть общий предок. С другой стороны, в C++ это не всегда так. Я попробовал это с помощью утиного набора, но компилятор выдает сообщение об ошибке:
template <typename T>
void generic_fcn(T argument) {
argument.first();
}
template <typename T>
void generic_fcn(T argument) {
argument.second();
}
Итак, мой вопрос: возможна ли реализация такого поведения без создания ненужного шаблонного кода путем специализации каждого отдельного случая?