#c #c 11
#c #c 11
Вопрос:
Во-первых, возможно ли наследовать std::tuple от чего-либо?
У меня есть
std::tuple<A, B> // (common base event data)
std::tuple<C, D, E> someObj;
Поэтому, если я создам второй кортеж, также должен быть задействован первый базовый класс (или что-то в этом роде).
Во-вторых, и я полагаю, что более важно, во время выполнения я хочу выбрать правильную виртуальную функцию на основе моего типа.
Так, например, если
std::tuple<A,B> { virtual void Serialize(); }
Я хотел бы иметь возможность использовать специальный метод Specialize дочернего класса, но с использованием шаблонов, чтобы его можно было расширить во время компиляции, но я могу выбрать метод во время выполнения.
Я подумываю о том, чтобы по-другому структурировать проблему в коде, чтобы я мог достичь этого, но если нет, мне придется прибегнуть к написанному вручную шаблонному коду для каждого кортежа.
Комментарии:
1. Нет, a
std::tuple
не может наследовать от какого-либо другого класса или какого-либо другого кортежа. И ваш второй пример вообще не имеет смысла. У кортежей нет виртуальных методов.2. Вероятно, вам лучше просто писать классы для хранения ваших данных. Почему вы хотите использовать
std::tuple
?3. Ваш пример не является кодом C . Ни один из ваших блоков кода не является допустимым кодом C . Я понимаю, вы не имели в виду, что это код на C , но остальная часть вашего сообщения недостаточно последовательна, чтобы понять, о чем вы говорите. «что-то вроде этого», «Я полагаю», «на основе моего типа», «правильный», «специальный дочерний элемент», «отличается от структуры» — много бессмыслицы или неопределенного размахивания руками. Пожалуйста, включите как можно больше реального кода. Объясните, что пошло не так. Объясните, что вы пытаетесь сделать, максимально привязав к конкретному коду, насколько это возможно. Объясните, почему вы это делаете.
Ответ №1:
Кортеж не будет волшебным образом расширять другой кортеж, который вы хотите. Вместо этого вы можете предоставить свою собственную логику:
template<typename... Types>
using child_tuple = std::tuple<A, B, Types...>
template<typename... Args>
auto make_child_tuple(A a, B b, Argsamp;amp;... args) {
return child_tuple<std::decay_t<Args>...>{a, b, std::forward<Args>(args)...};
}
если вам нужна виртуальная функция в кортеже (тьфу, не надо), вам придется вводить свои собственные структуры:
struct Interface {
virtual void serialize() = 0;
};
template<typename... Types>
struct poly_child_tuple: Interface, child_tuple<Types...> {
void serialize () override { /* ... */ }
};
Тем не менее, я настоятельно рекомендую вам предоставить общую функцию сериализации для ваших кортежей в виде функции шаблона (пожалуйста, сделайте):
template<typename... Types, std::size_t... S>
void serialize(std::index_sequence<S...>, const std::tuple<Types...>amp; tuple) {
int unpack[] = {(static_cast<void>(
[](autoamp;amp; value){
// Do things for each `value` in `tuple`
}(std::get<S>(tuple))
), 0)..., 0};
}
template<typename... Types>
void serialize(const std::tuple<Types...>amp; tuple) {
serialize(std::index_sequence_for<Types...>{}, tuple);
}
Затем, с помощью этой реализации, вы можете вызвать либо непосредственно вызвать его для кортежа известных типов, либо вы можете вызвать его из виртуального метода, который вы описали в своем вопросе.
Вот пример использования:
template<typename... Types>
struct serializable_tuple_impl : Interface {
void serialize() override {
::serialize(tuple);
}
private:
child_tuple<Types...> tuple;
};