Обработайте определения типов по шаблону - Какова Ваша работа вокруг?

Один подход к выравниванию рекурсивной структуры класса с рекурсивной функцией.

Вот класс, который мы хотели бы сгладить:

public class Nested {
    public let n : Int
    public let sub : [Nested]?
    public init(_ n:Int, _ sub:[Nested]?) {
        self.n = n
        self.sub = sub
    }
}

Вот функция, которая демонстрирует как это можно сделать:

func test() {
    let h = [
        Nested(1, [Nested(2, nil), Nested(3, nil)])
    ,   Nested(4, nil)
    ,   Nested(5, [Nested(6, nil), Nested(7, [Nested(8, nil), Nested(9, nil)])])
    ]
    func recursiveFlat(next:Nested) -> [Nested] {
        var res = [Nested]()
        res.append(next)
        if let subArray = next.sub {
            res.appendContentsOf(subArray.flatMap({ (item) -> [Nested] in
                recursiveFlat(item)
            }))
        }
        return res
    }
    for item in h.flatMap(recursiveFlat) {
        print(item.n)
    }
}

Сердцем этого подхода является локальная функция recursiveFlat. Он добавляет содержимое вложенного объекта к результату, а затем условно вызывает себя для каждого элемента, чтобы добавить его содержимое.

71
задан Yochai Timmer 7 August 2012 в 15:11
поделиться

2 ответа

, Что Вам нравится использовать в качестве работы вокруг? Контейнерные объекты или Макросы? Вы чувствуете стоящий того?

канонический путь состоит в том, чтобы использовать метафункцию как таким образом:

template <typename T>
struct my_string_map {
    typedef std::map<std::string, T> type;
};

// Invoke:

my_string_map<int>::type my_str_int_map;

Это также используется в STL (allocator::rebind<U>) и во многих библиотеках включая Повышение. Мы используем его экстенсивно в биоинформатическая библиотека .

Это чрезмерно увеличено в размере, но это - лучшие альтернативные 99% времени. Используя макросы здесь не стоит многих оборотных сторон.

(РЕДАКТИРОВАНИЕ: я исправил код для отражения соглашений Повышения/STL, как указано Daniel в его комментарии.)

103
ответ дан Konrad Rudolph 24 November 2019 в 13:04
поделиться
 Шаблон 
struct my_string_map: public std :: map 
 {
 };
 

Вы не должны наследовать от классов, которые не имеют виртуального деструктора. Это связано с деструкторами в полученных классах, не вызываемых, когда они должны быть, и вы можете в конечном итоге с нераспределенной памятью.

Это говорит, что вы можете *****, вероятно, ***** сойти с ним в приведенном выше экземпляре, потому что вы не добавляете больше данных в ваш производный тип. Обратите внимание, что это не одобрение. Я все еще советую вам не Сделай это. Тот факт, что вы могут , это не значит, что вы должны .

Редактировать: Да, это ответ на пост Shachris23. Я, наверное, пропустил что-то, потому что он появился над его / ее сообщением, а не ниже.

10
ответ дан 24 November 2019 в 13:04
поделиться
Другие вопросы по тегам:

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