其他分享
首页 > 其他分享> > c – 作为模板参数的功能的扣除指南

c – 作为模板参数的功能的扣除指南

作者:互联网

We can use std::unique_ptr to hold a pointer allocated with malloc which will be freed appropriately.
但是,生成的std :: unique_ptr的大小将是2个指针,一个用于指向对象的指针,一个用于指向删除函数的指针,而不是通常的指向对象的指针和隐式删除.正如一个答案所指出的,可以通过编写知道正确删除函数的自定义Unique_ptr来避免这种情况.可以使用模板参数使该函数知道,以支持任何删除函数,如下所示:

template <class T, void (*Deleter)(T *)>
struct Unique_ptr {
    explicit Unique_ptr(T *t, void (*)(T *))
        : t{t} {}
    ~Unique_ptr() {
        Deleter(t);
    }
    //TODO: add code to make it behave like std::unique_ptr

    private:
    T *t{};
};

template <class T>
void free(T *t) {
    std::free(t);
}

char *some_C_function() {
    return (char *)malloc(42);
}

int main() {
    Unique_ptr<char, free> p(some_C_function(), free); //fine
    Unique_ptr q(some_C_function(), free);             //should be fine
                                                       //with the right
                                                       //deduction guide
}

如果我们可以使用演绎指南而不必指定模板参数,那将非常好.不幸的是我似乎无法正确使用语法.这些尝试无法编译:

template <class T, auto Deleter>
Unique_ptr(T *, Deleter)->Unique_ptr<T, Deleter>;

template <class T, void (*Deleter)(T *)>
Unique_ptr(T *, void (*Deleter)(T *))->Unique_ptr<T, Deleter>;

或者,可以写出Unique_ptr< free> Q(some_C_function());为了手动指定函数模板参数,但这会产生推断T的问题.

什么是使Unique_ptr q(some_C_function(),free)的正确推论指南;或者Unique_ptr< free> Q(some_C_function());编译?

解决方法:

为什么要写自己的unique_ptr?只需将std :: unique_ptr与自定义删除指针一起使用即可.使用C 17,这非常简单:

template <auto Deleter>
struct func_deleter {
    template <class T>
    void operator()(T* ptr) const { Deleter(ptr); }
};

template <class T, auto D>
using unique_ptr_deleter = std::unique_ptr<T, func_deleter<D>>;

或者,正如Yakk建议的那样,更普遍:

template <auto V>
using constant = std::integral_constant<std::decay_t<decltype(V)>, V>;

template <class T, auto D>
using unique_ptr_deleter = std::unique_ptr<T, constant<V>>;

这会让你:

unique_ptr_deleter<X, free> ptr(some_c_api());

当然,你必须实际写X,但你没有空间开销.为了使用演绎指南完成相同的操作,您需要包装函数删除器以将其提升为模板参数:

template <class T, auto D>
Unique_ptr(T*, func_deleter<D>) -> Unique_ptr<T, func_deleter<D> >;

将使用如下:

Unique_ptr ptr(some_c_api(), func_deleter<free>());

我不确定这一定是否更好,并且遇到了导致标准没有std :: unique_ptr的演绎指南的所有相同问题(即:区分指针和数组).因人而异.

标签:template-deduction,c,templates,c17
来源: https://codeday.me/bug/20190828/1750733.html