C++
- 184 ответа
- 0 вопросов
288
Вклад в тег
p = { s };
- это Copy Initialization.Protocol::Protocol(Serial &s)
. Следом, через operator =
, который сводится к конструктору копирования/перемещения, ты делаешь Copy Construction объекта p
. Делается это через конструктор копирования/перемещения по умолчанию, который просто копирует/перемещает поля используя их конструкторы копирования/перемещения.Serial
, а сам temporary local уничтожается сразу же после конструирования p
.this
.p = { s };
, а p{ s };
или, как ты уже описал, p = s;
. Такой тип инициализации уже называется Value Initialization. Но по своей сути это только отсрочка проблемы. Тебе придется очень пристально следить за жизнью такого объекта, т.к. вероятность обрести все тот же висячий указатель в замыкании в следствии неявного копирования крайне высока.std::enable_shared_from_this
[?], std::shared_ptr
[?] для хранения протокола и std::weak_ptr
[?] в замыкании твоей лямбды. Этот метод гарантированно решит твою проблему, но может привести к ряду других проблем с возможной утечкой ресурсов.Serial
отцеплять лямбду уничтожаемого Protocol
и написать правильный конструктор копирования Protocol
, соблюдая правило 3/5/0.Because of argument-dependent lookup, non-member functions and non-member operators defined in the same namespace as a class are considered part of the public interface of that class (if they are found through ADL)
operator>>
никакими магическими силами не переносится в глобальное пространство имен. Он просто находится по ADL, т.к. правильно реализован и является частью интерфейса соответствующего типа. auto out = in;
The lifetime of a temporary object may be extended by binding to a const lvalue reference or to an rvalue reference (since C++11), see reference initialization for details.
template< typename U, typename... args >
void mapClasses()
{
// ...
if constexpr( sizeof...( args ) > 0 ) // Все понятно и без слов.
{
mapClasses<args...>();
}
}
template< typename... args >
struct Map;
template< typename U >
struct Map<U>
{
static inline void mapClasses()
{
// ...
}
};
template< typename U, typename... args >
struct Map<U, args...>
{
static inline void mapClasses()
{
Map<U>::mapClasses();
Map<args...>::mapClasses();
}
};
template< typename U >
void mapClasses()
{
// ...
}
// SFINAE тут (аргумент функции) выключит вывод шаблона при пустом списке полей.
// В этом случае доступным остается только верхний экземпляр функции.
template< typename U, typename... args >
void mapClasses( char (*)[ sizeof...( args ) > 0 ] = 0 )
{
mapClasses<U>();
mapClasses<args...>();
}