Совместимость для кода C ++ 11, предназначенного для Visual Studio 2008

У меня есть внутренняя дискуссия о том, как я поддерживаю компилятор до 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. Я не делаю ничего сумасшедшего, что было бы трудно сделать бэкпорт (без кортежей, лямбд или других вещей, которые были бы проблематичными в этом контексте).

Кто-нибудь должен был сделать что-то подобное раньше и нашел хорошее решение?

2

Решение

Поскольку у меня недостаточно репутации, чтобы комментировать, я постараюсь дать ответ.

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;
}

В качестве общего совета я бы действительно попытался спрятать вещи, специфичные для ОС / компилятора, в нескольких низкоуровневых классах / файлах и использовать там все, что вам нужно. Но держите все чудовищные вещи в коде своего приложения как можно лучше.

Надеюсь, это поможет!

2

Другие решения