Есть у меня рабочий проект, который состоит из разделяемой библиотеки и утилит, которые выполняют прикладные задачи, дергая из неё функции. ПО пишется под Linux+Windows, и есть требования не использовать сторонние библиотеки. Из-за этого библиотека предоставляет не только функции, решающие конкретную проблему, но и всякие обёртки: рекурсивное сканирование каталога, чтение настроек из ini-подобного файла и т.д. И есть также требование, чтобы интерфейс библиотеки был максимально бинарно совместим: под Windows мы собираем в Visual Studio 2008, а другие проекты, юзающие библиотеку, могут быть собраны и в 2010, например; или в Линуксе мы собираем gcc + libstdc++, а клиенты библиотеки могут быть собраны чрез clang + libc++. Из-за этого интерфейс библиотеки оперирует только POD-типами данных и абстрактными классами с фабриками.
На примере функции сканирования каталога проиллюстрирую свою проблему. Не заморачиваясь на POD и совместимость, я бы написал её прототип так:
std::list<std::string> scanDir(const std::string &path)
Но стандартные контейнеры и строки по вышеописанным причинам в пролёте, а мне надо вернуть список.
Вижу два варианта:
1) пишем интерфейс «итератор по файлам», внутри либы пишем реализацию итератора, который хранит в себе std::list<std::string>, позволяет бегать по нему;
2) пишем интерфейс «коллбэк», передаём его в ф-цию, та его дергает, а мы на стороне клиента уже строим std::list<std::string>.
Покритикуйте пожалуйста подходы. Может, есть третий вариант?