Вы можете написать простой огибающий агрегат, который будет препятствовать перемещению и копированию.
struct NoCopyMove {
NoCopyMove(NoCopyMove const&) = delete;
NoCopyMove(NoCopyMove&&) = delete;
void operator=(NoCopyMove const&) = delete;
void operator=(NoCopyMove&&) = delete;
};
template<class Functor>
struct Fixed : Functor, NoCopyMove {
using Functor::operator();
};
template<typename F>
Fixed (F&&) -> Fixed<std::decay_t<F>>;
Для использования в таком виде
const auto l = Fixed{[]{}};
NoCopyMove
- это простой миксин, который отключает копирование и перемещение. Написание этого способа позволяет нам сохранить специализации Fixed
в виде простых агрегатов.
Все, что делает Fixed
, - это наследование / инициализация в качестве базового (с гарантированным исключением копирования, когда это возможно) для функтора, который он задается как аргумент. А затем выставьте его operator()
.
Поскольку в нем нет участвующих членов (кроме, может быть, в Functor
), и поскольку лямбда не может наследовать от нашего пользовательского класса NoCopyMove
, пустые базовые оптимизации запускаются для безгражданства лямбды. Таким образом, объекты не должны быть больше, чем лямбда, с которой вы их инициализируете.