А если использовать в разных библиотеках не саму функцию, а только registry - он будет работать правильно.
Если передать из одной библиотеки registry сформированный в другой, то из-за несоответствия индексов в storage будет получен не тот вектор значений.
В представленном решении используется unordered_map<type_index, any>. Если использовать std::type_index или соответствующий hash_code, то таких проблем не будет.
А как же классический if constexpr? Или enable_if, или requires на сам метод test_running_time? Тогда и boid не потребовался бы. Или у этого типа есть ещё какой то смысл?
Так исторически сложилось. Такое соглашение о форматировании кода в большинстве проектов, в которых я участвовал. Похоже, Qt оказал влияние). Но всегда для удобства можно использовать псевдонимы для пространств имен.
Развиваю библиотеку "умных" оберток https://habr.com/ru/post/650701/ и для меня это нововведение весьма полезно. Сейчас код представляет собой большую портянку макросов (например, здесь https://gitlab.com/ssoft-scl/module/feature/-/blob/main/src/Detail/Operator.h), от которых теперь можно легко избавиться. Не думаю, что такой стиль будет распространён в прикладных программах, а вот инструментальные библиотеки типа std, boost и др. обязательно это будут использовать.
Если "потокобезопасность" это добавление на каждую операцию лока, то это не потокобезопасность
Средства библиотеки позволяют сделать операцию lock, как на каждую операцию отдельно, так и на любой блок кода, в зависимости от желаний разработчика. На постоянной основе сейчас можно сделать блокировку так
using Map = Wrapper< map, ThreadSafe::RecursiveMutex >;
Map map;
void foo ()
{
// в месте, где нужен постоянный lock
auto map_ptr = ↦
// map_ptr - умный указатель, который выполнил lock
if ( map_ptr->empty() )
map_ptr->doAnything();
}
Совершенно согласен с таким утверждением. Однако, из многочисленных вариантов возможной реализации данный вариант оказался наиболее компактным и совместимым с использованием обычных типов. В некоторых случаях имеется возможность реализации оператора неявного преобразования обертки к базовому типу, тогда код будет иметь привычный вид.
for ( const auto & value : values )
cout << value << endl;
Подход strong typedef к простой декларации новых типов на основе существующих известен достаточно давно и имеет свою реализацию, например, в Boost. Здесь показана возможность реализации такого подхода с помощью "умной" обертки на основе примера из доклада на коференции CppCon 2018.
И FileName и Url являются отдельными типами, а не синонимами. В этом весь смысл.
Если передать из одной библиотеки
registry
сформированный в другой, то из-за несоответствия индексов вstorage
будет получен не тот вектор значений.В представленном решении используется
unordered_map<type_index, any>
. Если использоватьstd::type_index
или соответствующийhash_code
, то таких проблем не будет.При такой регистрации типа возможна очень нехорошая ситуация.
При сборке разных библиотек в каждой из них будет своя собственная последовательность индексов type_index, а при сборке приложения вообще другая.
Для примера можно реализовать foolib с методом
затем barlib с методом
а затем в тестовом приложении сделать так
и получить на выходе
А как же классический if constexpr? Или enable_if, или requires на сам метод test_running_time? Тогда и boid не потребовался бы. Или у этого типа есть ещё какой то смысл?
Так исторически сложилось. Такое соглашение о форматировании кода в большинстве проектов, в которых я участвовал. Похоже, Qt оказал влияние). Но всегда для удобства можно использовать псевдонимы для пространств имен.
Развиваю библиотеку "умных" оберток https://habr.com/ru/post/650701/ и для меня это нововведение весьма полезно. Сейчас код представляет собой большую портянку макросов (например, здесь https://gitlab.com/ssoft-scl/module/feature/-/blob/main/src/Detail/Operator.h), от которых теперь можно легко избавиться.
Не думаю, что такой стиль будет распространён в прикладных программах, а вот инструментальные библиотеки типа std, boost и др. обязательно это будут использовать.
Средства библиотеки позволяют сделать операцию lock, как на каждую операцию отдельно, так и на любой блок кода, в зависимости от желаний разработчика. На постоянной основе сейчас можно сделать блокировку так
Не откладывая в долгий ящик, всё в проекте поправил. Спасибо за замечание, действительно глаз режет.
Совершенно согласен с таким утверждением. Однако, из многочисленных вариантов возможной реализации данный вариант оказался наиболее компактным и совместимым с использованием обычных типов.
В некоторых случаях имеется возможность реализации оператора неявного преобразования обертки к базовому типу, тогда код будет иметь привычный вид.
Как раз над этим сейчас и работаю).
Подход strong typedef к простой декларации новых типов на основе существующих известен достаточно давно и имеет свою реализацию, например, в Boost.
Здесь показана возможность реализации такого подхода с помощью "умной" обертки на основе примера из доклада на коференции CppCon 2018.
И FileName и Url являются отдельными типами, а не синонимами. В этом весь смысл.