我正在寻找一个标准的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;
}
ptr1
和ptr2
工作一样,但ptr2
是成功的一半大小,因为它并不需要存储指向std::free
。
我的问题:是否有一个标准库的方式来做到这一点,所以我不需要定义fn_t
和fn_ref
?
函数是一种类型。 –
@JoelCornett:函数不是一种类型。如果你试图提供'std :: free'作为类型参数,编译器会发出一个错误:“模板参数列表中参数1的类型/值不匹配”(“注:预期类型,得到'空闲'”)。函数*有*类型,但函数*不是类型。并且函数的类型对于该函数不是唯一的。 'decltype(std :: free)'是'void(void *)throw()',这个类型没有'operator()'。 –
哈哈哎呀,这是我的'type-o'。我的意思是相反的。 –