通用C++函数包装

Generic C++ function wrapping

本文关键字:包装 函数 C++ 通用      更新时间:2023-10-16

我将编写一个简单的通用智能指针模板,该模板允许程序员在调用某些函数FUNC()之前和之后应用任意数量的包装例如,如果要求启动计时器、锁定、log_start、FUNC()、log_end、解锁、停止计时器

然后,我希望能够编写一些简单的东西,程序员向模板提供3种类型和一个函数,然后让编译器完成其余的工作。我有一种感觉,使用可变模板可以完成这项工作,其方式类似于类型列表与重载运算符的结合->

class timer {}; // ctor start timer, dtor stop timer
class locker{}; // ctor lock, dtor unlock
class logger{}; // ctor lock, dtor unlock

然后一些代码,如

template <typename ...base_class_list> 
class aggregate : public base_class_list... {};
using pre_conditions = aggregate<logger, locker, trans>;
class gadget 
{
    auto do_something() -> void;
}; // gadget

最后(我想写但不知道如何把粘在一起的部分

SMART_PTR<pre_conditions, gadget> g;
g->do_something();

使用Bjarne Stroustrup在"包装C++成员函数调用"中描述的方法,我可以很容易地使其工作,但我想知道是否有更通用、更优雅的解决方案。

简单的方法是只包装所有operator():

template <typename T, typename ... Ts>
struct magic
{
    T obj;
    template <typename ... Us>
    decltype(auto) operator ()(Us...args)
    {
        ordered_tuple<Ts...> t; // tuple doesn't guaranty order
        obj(std::forward<Us>(args)...);
    }
};

演示

要包装operator ->,它更棘手:

template <typename T, typename ... Ts>
class wrapper
{
    ordered_tuple<Ts...> t; // tuple doesn't guaranty order
    T* obj;
public:
    wrapper(T* obj) : obj(obj) {}
    T* operator ->()
    {
        return obj;
    }
};
template <typename T, typename ... Ts>
class magic
{
    T obj;
public:
    wrapper<T, Ts...> operator ->()
    {
        return {&obj};
    }
};

演示

还应该处理const和非默认构造函数。(并找到更好的名字)。