Я уверен, что есть название для того, что я ищу, я просто не знаю его (и если бы я знал, я бы, наверное, уже нашел ответ).По сути, я хочу реализовать свою собственную облегченную версию std::function
для спорта.Я хочу инициализировать его с помощью лямбды, а затем вызвать его.Я могу обернуть лямбду своим классом-оберткой для шаблона, ничего для него:
struct CInvokableAbstract {
virtual ~CInvokableAbstract() = default;
};
template <class InvokableObject>
struct CInvokableBasic : public CInvokableAbstract
{
CInvokableBasic(InvokableObject&& target) : _invokable(std::move(target)) {}
template <typename... Args>
typename std::result_of<decltype(&InvokableObject::operator())(Args...)>::type operator()(Args... args) const
{
return _invokable(std::forward<Args>(args)...);
}
private:
InvokableObject _invokable;
};
Теперь я могу сделать мой класс семантически похожим на std::function
, но как я могу сохранить точный тип лямбды вЧтобы преобразовать стертый объект обратно в его исходный конкретный тип?
struct CInvokableDeferred
{
template <class InvokableObject>
CInvokableDeferred(InvokableObject&& target) noexcept : _invokable(std::make_unique<CInvokableBasic<InvokableObject>>(std::move(target))) {}
template <typename... Args>
void operator()(Args... args) const
{
// How can I know the original concrete type to cast this to?
static_cast<???>(_invokable.get())->(std::forward<Args>(args)...);
}
private:
std::unique_ptr<CInvokableAbstract> _invokable;
};
Я не могу придумать какой-либо хитрости шаблона, которая могла бы это сделать, но мы знаем, что это возможно (если std::function
не использует некоторыевстроенные компиляторы, или иначе реализованные внутри компилятора, а не обычный код C ++.
Обратите внимание, что я использую компилятор, который не имеет полной поддержки C ++ 17, поэтому я могуНе используйте, например, auto
-возвратный тип возврата.