170 похожих чатов

Привет, как я могу заиметь в базовом классе не только

виртуальные методы, но и "виртуальный" тип, таким образом я бы мог его переопределить в производном классе?
Хочется сделать что-то вроде:
class IteratorBase {
public:
using Out; // <<< to be defined
virtual ~IteratorBase() { }
virtual Out next() = 0;
virtual unsigned long sizeHint() const = 0;
};

template<class Container>
class OwnIterator : public IteratorBase {
public:
using IterType = typename std::remove_const<typename Container::const_iterator>::type;
using Out = typename std::iterator_traits<typename Container::const_iterator>::value_type;
private:
Container container;
IterType iter;
public:
OwnIterator(Container c) : container(std::move(c)), iter(container.begin()) {}

Out next() { ... return *iter; }
...
// and so on
...
};

16 ответов

15 просмотров

То есть в производном классе я определяю тип Out на нужный. Как подобные задачи решаются в C++?

Можно параметризовать интерфейс этим типом, правда это будут разные интерфейсы (на каждый Out - свой): template <class Out> class IteratorBase

Danya🔥
CRTP например...

Ну точнее просто передать как шаблонный параметр, да

𝙽𝚒𝚌𝚔 𝙻𝚒𝚗𝚔𝚎𝚛
Не то.

Тогда никак. Функция возвращает фиксированный тип. Виртуальная не может быть шаблоном. Значит нужно параметризовать класс.

Как вы предполагаете возвращать разные типы из функции, которая выбирается уже в рантайме? IteratorBase* base = /* ... */; auto next = base->next(); ^^^^ должен быть известен компилятору в компилтайме Что должен компилятор подставить на место auto? Угадать намерения программиста? А если программист хочет невозможного?

Ofee Oficsu
Как вы предполагаете возвращать разные типы из фун...

Я могу ограничить все Out-ы ограничить типами с одинаковым или ограниченным размером или, напротив, попросить пожаловаться компилятор, если у него не получается нужный тип вывести

𝙽𝚒𝚌𝚔 𝙻𝚒𝚗𝚔𝚎𝚛
Я могу ограничить все Out-ы ограничить типами с од...

Компилятор почти никогда не может вывести тип. Потому что наследник IteratorBase расположен в dll. Или скрыт в ядре ОС. А быть может, находится в памяти компьютера на тёмной стороне Луны и все запросы к нему выполняются по некоторому RPC Вы, вероятно, имеете ввиду, что у возвращаемого значения есть некоторый интерфейс? Правильно я понимаю, что вам кажется, что вы хотите type erasure на основе этого интерфейса?

Более-менее близкий вариант: объявить внутри базового интерфейсе ещё один struct IValue, возвращать std::unique_ptr<IValue> из next(). В наследниках реализовывать интерфейс. При желании это оптимизируется.

Alexander Karaev
Более-менее близкий вариант: объявить внутри базов...

Согласен, с тем недостатком, однако, что на unsigned long интерфейс не навесишь. Придётся похоже в next возвращать сырой указатель и на стороне клиента кастовать.

𝙽𝚒𝚌𝚔 𝙻𝚒𝚗𝚔𝚎𝚛
Согласен, с тем недостатком, однако, что на unsign...

Не совсем. Можно воспользоваться стиранием типа и в интерфейс завернуть вообще что угодно. Например, в наследнике будет struct Value : IValue { Out value; ... }

Ofee Oficsu
Компилятор почти никогда не может вывести тип. Пот...

Спасибо за детальное разъяснение. Данный приёмчик с типом-мембером довольно широко используется в Скале https://github.com/xmanu/scala-virtual-classes-annotation-macros У меня была гипотеза, что аналог есть и в плюсах

Похожие вопросы

Обсуждают сегодня

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Гайс, вопрос для разносторонее развитых: читаю стрим с юарта, нада выделять с него фреймы с определенной структурой, если ли чо готовое, или долбаться с ринг буффером? нада у...
Vitaly
9
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
длина пакета фиксированная, или меняется?
Okhsunrog
7
Карта сайта