本文介绍了将自由函数转换为DefaultConstructible函数对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一个类型,它会将自由函数转换为默认的可构造函数对象。

I'm looking for a type which would convert a free function to a default constructible function object.

它应该是一个类模板,模板参数:

It should be a class template which would take the function as a template parameter:

template<typename F, F P>
struct fn_to_type {
    template<class... Args>
    decltype(auto) operator()(Args&&... args) {
        return P(std::forward<Args>(args)...);
    }  
};

因此,它可以用作容器和智能指针的模板参数:

So it can be used as a template parameter for containers and smart pointers:

bool CloseHandle(void* handle);
using UniqueHandle = std::unique_ptr<void, fn_to_type<decltype(&CloseHandle), &CloseHandle>>;

bool FooLess(const Foo& lhs, const Foo& rhs);
using FooSet = std::set<Foo, fn_to_type<decltype(&FooLess), &FooLess>>;

标准库肯定没有这样的功能,但是Boost库可能吗?

The Standard library definitely doesn't have such function, but maybe the Boost libraries do?

我很好奇为什么这样的东西不在标准库中 - 是否有任何陷阱,我看不到?

Also I'm curious why such thing is not in the standard library - are there any pitfalls which I can't see?

如果没有这样的函数库,有没有办法改进这个 fn_to_type 的东西?例如。为了避免键入函数名两次?

And if there is no library with such function, is there a way to improve this fn_to_type thing? E.g. do something to avoid typing function name twice?

推荐答案

标准库已经有一个类,可构造的类类型:

The Standard Library already has a class which can convert a function pointer to a default-constructible class type:

template <class T, T v>
struct integral_constant {
    ...
    constexpr operator value_type() { return value; }
};

因此,它可以代替 fn_to_type class:

Thus it can be used instead of that fn_to_type class:

#include <type_traits>

bool CloseHandle(void* handle);
using UniqueHandle = std::unique_ptr<void, std::integral_constant<decltype(&CloseHandle), &CloseHandle>>;

bool FooLess(const Foo& lhs, const Foo& rhs);
using FooSet = std::set<Foo, std::integral_constant<decltype(&FooLess), &FooLess>>;

这篇关于将自由函数转换为DefaultConstructible函数对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-21 12:46