gpt4 book ai didi

将函数转换为函数对象类型的 C++ 模板

转载 作者:搜寻专家 更新时间:2023-10-31 00:36:04 26 4
gpt4 key购买 nike

我正在尝试将 std::unique_ptr 与自定义删除器一起使用,以简化管理从各种 C API 返回给我的句柄的生命周期。这在理论上很好,但我正在努力寻找一种在运行时最佳的方法,并且没有针对每种包装类型的大量样板。

例如,考虑一些不透明类型 foo,必须通过将其指针传递给 destroy_foo 来释放它:

// approach 1: pass destroy_foo at runtime (bad for performance)
using foo_ptr = std::unique_ptr<foo, decltype(&destroy_foo)>;
foo_ptr bar{create_foo(...), destroy_foo};


// approach 2: make a deleter type (verbose - for many types)
struct foo_deleter
{
void operator()(foo* p)
{
destroy_foo(p);
}
};
using foo_ptr = std::unique_ptr<foo, foo_deleter>;
foo_ptr bar{create_foo(...)};

第一种方法对于编译器来说很难优化,因为我传递了一个函数指针,所以它被淘汰了。第二种方法似乎不必要地冗长。我有很多这样的类型要管理,手动为每个类型创建一个类很痛苦。

我如何定义一个接受destroy_foo 并给我一个等同于foo_deleter 的类型的类模板?或者是否有标准库模板来执行此操作?

// best of both worlds - to_obj<Func> makes foo_deleter from destroy_foo...
using foo_ptr = std::unique_ptr<foo, to_obj<destroy_foo>>;
foo_ptr bar{create_foo(..)};

因此给定任何函数,模板将定义一个带有 operator() 的类,它简单地将所有参数转发给函数,并返回结果。

最佳答案

有点像

template<typename T, void (*func)(T*)>
struct Deleter{
void operator()(T* t) { func(t); }
};

??

或者如果你想要更强大的东西

template <typename t>
struct function_traits;

template <typename R, typename A>
struct function_traits<R (*)(A)>
{
using t_ret = R;
using t_arg = A;
};

template <typename F, F* f>
struct Functor
{
using FT = function_traits<F*>;
typename FT::t_ret operator()(typename FT::t_arg a) {
return f(a);
}
};


void mydeleter(int*);
#define FUNCTOR(F) Functor<decltype(F),&F>

或者使用 C++11 的全部功能

template <typename F, F* f>
struct Functor
{
template<typename... A>
auto operator()(A&&... a) -> decltype(f(std::forward<A>(a)...)) {
return f(std::forward<A>(a)...);
}
};

#define FUNCTOR(F) Functor<decltype(F),&F>

关于将函数转换为函数对象类型的 C++ 模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22553181/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com