简体   繁体   English

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

[英]Deduction guides for functions as template parameters

We can use std::unique_ptr to hold a pointer allocated with malloc which will be free d appropriately. 我们可以使用std::unique_ptr来保存一个用malloc分配的指针,它将适当地free However, the resulting std::unique_ptr 's size will be 2 pointers, one for the pointer to the object and one for the pointer to the deleter function instead of the usual 1 pointer to object and an implicit delete . 但是,生成的std::unique_ptr的大小将是2个指针,一个用于指向对象的指针,一个用于指向删除函数的指针,而不是通常的指向对象的指针和隐式delete As one answer points out this can be avoided by writing a custom Unique_ptr that knows the proper deleter function. 正如一个答案所指出的,可以通过编写知道正确删除函数的自定义Unique_ptr来避免这种情况。 This function can be made known using a template parameter to support any deleter function like so: 可以使用模板参数使该函数知道,以支持任何删除函数,如下所示:

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
}

This would be really nice if we could use deduction guides to not have to specify the template parameters. 如果我们可以使用演绎指南而不必指定模板参数,那将非常好。 Unfortunately I can't seem to get the syntax right. 不幸的是我似乎无法正确使用语法。 These attempts fail to compile: 这些尝试无法编译:

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>;

Alternatively one could write Unique_ptr<free> q(some_C_function()); 或者,可以编写Unique_ptr<free> q(some_C_function()); in order to manually specify the function template parameter, but that creates issues with deducing T . 为了手动指定函数模板参数,但这会产生推断T问题。

What is the correct deduction guide to make Unique_ptr q(some_C_function(), free); 什么是使Unique_ptr q(some_C_function(), free);的正确推论指南Unique_ptr q(some_C_function(), free); or Unique_ptr<free> q(some_C_function()); Unique_ptr<free> q(some_C_function()); compile? 编译?

Why write your own unique_ptr ? 为什么要写自己的unique_ptr Just use std::unique_ptr with a custom delete pointer. 只需将std::unique_ptr与自定义删除指针一起使用即可。 With C++17, that's very straightforward: 使用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>>;

Or, as Yakk suggests, more generally: 或者,正如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>>;

which gets you to: 这会让你:

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

Sure, you have to actually write X , but you have no space overhead. 当然,你必须实际写X ,但你没有空间开销。 In order to accomplish the same thing with deduction guides, you'd need to wrap the function deleter in order to lift it to a template parameter: 为了使用演绎指南完成相同的操作,您需要包装函数删除器以将其提升为模板参数:

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

Which would be used like: 将使用如下:

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

I'm not sure that's necessarily better, and you run into all the same problems that led to the standard not having deduction guides for std::unique_ptr (ie: differentiating between pointers and arrays). 我不确定这一定是否更好,并且遇到了导致标准没有 std::unique_ptr演绎指南的所有相同问题(即:区分指针和数组)。 YMMV. 因人而异。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM