Kann ich einen boost::function<void()>
in diese Warteschlange schieben?
Nicht direkt, wie boost::function<void()>
ist ein Schwergewicht besitzender Typ-gelöschten Wrapper, die nicht implizit umwandelbar in einen Funktionszeiger und auch einige Daten gespeichert ist.
Wenn Sie eine trivialer zuweisbare eine trivialen-zerstörbare Art benötigen, die ein Funktionsobjekt verweisen kann, könnten Sie eine function_view
Klasse implementieren, ohne es zu besitzen bis zu einem gewissen Funktionsobjekt verweist. Wenn Sie mit den Lebensdauern vorsichtig sind und sicherstellen, dass function_view
immer auf "Live-Objekte" zeigt, können Sie Instanzen davon in Ihrer Warteschlange sicher speichern.
Konzeptionell function_view
ist ein Paar Zeiger. Ich habe eine Implementierung in meinem "passing functions to functions" Artikel, die ich weiter unten einfügen bin:
template <typename TReturn, typename... TArgs>
class function_view<TReturn(TArgs...)> final
{
private:
using signature_type = TReturn(void*, TArgs...);
void* _ptr;
TReturn (*_erased_fn)(void*, TArgs...);
public:
template <typename T, typename = std::enable_if_t<
std::is_callable<T&(TArgs...)>{} &&
!std::is_same<std::decay_t<T>, function_view>{}>>
function_view(T&& x) noexcept : _ptr{(void*)std::addressof(x)}
{
_erased_fn = [](void* ptr, TArgs... xs) -> TReturn {
return (*reinterpret_cast<std::add_pointer_t<T>>(ptr))(
std::forward<TArgs>(xs)...);
};
}
decltype(auto) operator()(TArgs... xs) const
noexcept(noexcept(_erased_fn(_ptr, std::forward<TArgs>(xs)...)))
{
return _erased_fn(_ptr, std::forward<TArgs>(xs)...);
}
};
Diese Klasse übergibt die folgenden Tests:
using type = function_view<void()>;
static_assert(is_trivially_assignable<type, type>{});
static_assert(is_trivially_destructible<type>{});
live example on wandbox
, aber dann müssen Sie sich sorgen, dass die Ansicht kein gültiges Objekt anzeigt. Das bedeutet, dass Sie die Lebensdauer der Funktion verwalten müssen. Es ist hart, wenn man über Threading spricht. Wie würdest du wissen, dass die Ansicht ihre Arbeit getan hat und du die Funktion löschen kannst? –
@DavidHaim: es hängt vom Anwendungsfall des OP ab. Wenn die Ownership/Lifetime-Hierarchie unklar ist, ist ein 'shared_ptr' /' unique_ptr' besser geeignet. Aber wenn er einen "Elternbereich" hat, in dem alle Funktionen leben, oder eine Art "Manager", in dem er Funktionen speichern kann, ist eine Ansicht vielleicht besser/effizienter. –
@VittorioRomeo Um Ihre Frage zu beantworten: In meinem Szenario gibt es keinen Manager, der die Funktionen besitzt. –