У меня есть классы A1, A2 и B:
struct A1 { int call(int); };
struct A2 { double call(double); };
struct B : public A1, public A2 {};
Из-за того, что имя «вызов» является общим для A1 и A2, компилятор скрывает эти имена в B, даже если подписи не совпадают.
struct B { void do_stuff() { call(int(0)); /* call? call what? *ERROR* */ } };
Итак, я продолжаю и выбрасываю некоторые объявления об использовании:
struct B { using A1::call; using A2::call; void do_stuff() { call(int(0)); } };
И все в порядке. Но что, если А1 и А2 имеют много членов с одинаковыми именами, напр. A1 и A2 являются специализациями для некоторого шаблонного класса, и мы хотим, чтобы B содержал членов обоих под одной крышей? Тогда это заканчивается тем, что выглядит … ну, очень тяжело.
struct B {
using A1::call; using A2::call;
using A1::asdf; using A2::asdf;
using A1::other_thing; using A2::other_thing;
...
};
Я должен сделать это для десятков классов, унаследованных от низкоуровневых специализаций классов. Есть ли какая-нибудь конструкция, которая облегчила бы эту раскладку клавиатуры и ад читабельности?
Что-то вроде using A1::*
если с помощью объявлений как-то поддерживается глобализация.
Обновить:
Я пришел к решению, которое рекурсивно размещает объявления использования в псевдо-вариационной иерархии шаблонов. На самом деле он выглядит действительно чистым, глядя в коде клиента, примерно так:
class B : mixins<A1,A2> {
void do_stuff() {
call(int(0)); // I'm not a compiler error!
call(double(0)); // neither am I!
}
};
Я опубликую детали как ответ, если никто больше не придумает ничего.
Задача ещё не решена.
Других решений пока нет …