У меня есть внутренняя дискуссия о том, как я поддерживаю компилятор до C ++ 11 — Visual Studio 2008. Это необходимо для сборки под Windows 2000 (не спрашивайте!).
Я использую несколько функций C ++ 11, таких как std :: to_string, std :: mutex и так далее. В настоящее время я смог получить низкоуровневые проекты для компиляции с помощью boost
а также tr1
лайк:
#if _MSC_VER == 1500
# include <boost/thread/lock_guard.hpp>
using boost::lock_guard;
# include <boost/thread/mutex.hpp>
using boost::mutex;
# include <memory>
using std::tr1::shared_ptr;
#else
# include <mutex>
using std::lock_guard;
using std::mutex;
# include <memory>
using std::shared_ptr;
using std::unique_ptr;
#endif
и изменив источник на shared_ptr func_name()
вместо std::shared_ptr func_name()
, например. Далеко от совершенства, и, без сомнения, скоро возникнут тонкие внутренние проблемы.
Я сейчас пытаюсь разобраться std::to_string
, который нельзя так легко адаптировать к буст-версии (в других классах, вероятно, еще есть проблемы, с которыми я еще не сталкивался).
Насколько я вижу, у меня есть два варианта:
1) Укусить пулю и препроцессор отделить весь код обратной совместимости. Это изменит и увеличит объем кода для чего-то, что не будет использоваться в 99% случаев — но будет значительно быстрее реализовано.
2) Получите из std :: string и добавьте недостающую функциональность по мере необходимости. Повторите для других классов / функций. Это потребует «использования неизвестных классов» для людей, незнакомых с проектом, а также дополнительного временного кодирования, чтобы заполнить эти пробелы, с возможностью появления ошибок, но быть самым чистым решением. Он также может быть использован для будущих исправлений совместимости.
Замена каждого типа не является большой задачей, но я бы хотел сохранить необработанные типы реализации везде, где это возможно, тем более что код должен работать и в Linux, и в BSD. Я не делаю ничего сумасшедшего, что было бы трудно сделать бэкпорт (без кортежей, лямбд или других вещей, которые были бы проблематичными в этом контексте).
Кто-нибудь должен был сделать что-то подобное раньше и нашел хорошее решение?
Поскольку у меня недостаточно репутации, чтобы комментировать, я постараюсь дать ответ.
std :: to_string является автономной функцией, поэтому нет необходимости ее извлекать. В зависимости от того, насколько важны скорость / форматирование, вы можете реализовать шаблонную функцию my :: to_string с boost :: lexical_cast или std :: stringstream. Если скорость действительно имеет значение, вам следует потратить немного больше времени и вручную создать перегрузки, использующие std :: sprintf.
Вот пример для первого пути:
#include <boost/lexical_cast.hpp>
#include <string>
#include <iostream>
namespace my {
template<typename T> std::string to_string(T val){
return boost::lexical_cast<std::string>(val);
}
}
int main(){
std::string foo = my::to_string(42.23);
std::cout << foo << std::endl;
return 0;
}
В качестве общего совета я бы действительно попытался спрятать вещи, специфичные для ОС / компилятора, в нескольких низкоуровневых классах / файлах и использовать там все, что вам нужно. Но держите все чудовищные вещи в коде своего приложения как можно лучше.
Надеюсь, это поможет!