我正在寻找一个标准的C++ 14类型模板,静态地(在编译时)嵌入一个函数引用作为模板参数,并实现operator()
作为对引用函数的转发调用.
我知道std::function
存在,但它将函数指针存储为数据成员.我希望将函数引用嵌入到类型签名中,以便包装器类型为空且默认可构造.
我有一个工作实现(使用示例用例):
#include <cstring>
#include <iostream>
#include <memory>
// Implementation:
template <typename Ret, typename... Args>
struct fn_t {
template <Ret (Func)(Args...)>
struct fn_ref {
Ret operator () (Args &&...args) const {
return Func(std::forward<Args>(args)...);
}
};
};
// Example use case:
template <typename T>
using unique_c_ptr = std::unique_ptr<T, fn_t<void, void *>::fn_ref<std::free>>;
int main() {
// { char *, void (*)(void *) } (16 bytes)
std::unique_ptr<char[], decltype(&std::free)> ptr1(::strdup("Hello"), &std::free);
// { char *, fn_t<void, void *>::fn_ref<std::free> } (8 bytes)
unique_c_ptr<char[]> ptr2(::strdup("Hello"));
std::cout << sizeof ptr1 << '\n' // 16
<< sizeof ptr2 << std::endl; // 8
return 0;
}
Run Code Online (Sandbox Code Playgroud)
ptr1
并且ptr2
工作相似,但是ptr2
只有一半大小,因为它不需要存储指针std::free
.
我的问题:是否有标准库方式这样做,这样我就不需要定义fn_t
和fn_ref
?
std::integral_constant
这项工作有哪些:
using CFree = std::integral_constant<void (*)(void*), std::free>;
Run Code Online (Sandbox Code Playgroud)
由于它可能会转换为其值,因此您可以使用相同的语法来调用operator()
.