スタティック(コンパイル時に)関数のリファレンスをテンプレート引数として埋め込み、参照された関数への転送呼び出しとしてoperator()
を実装する標準のC++ 14タイプのテンプレートを探しています。標準の静的関数ラッパー型テンプレートはありますか?
私は、std::function
が存在することを知っていますが、データメンバーとして関数ポインタを格納しています。ラッパーの型がemptyとdefault-constructibleになるように、関数の参照を型シグネチャに埋め込むようにします。
私は(例えば、ユースケース付き)作業の実装を持っている:
#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
作業問わず、それがstd::free
へのポインタを格納する必要がないため、ptr2
は半分のサイズです。
私の質問:fn_t
とfn_ref
を定義する必要がないように、標準ライブラリの方法がありますか?
機能はタイプです。 –
@JoelCornett:関数は型ではありません。型引数として 'std :: free'を指定しようとすると、コンパイラは"型/値の不一致がテンプレートパラメータリストの引数1にあります "("型が予期しています。関数*は型を持ちますが、関数*は型ではありません。関数の型は、その関数に固有のものではありません。 'decltype(std :: free)'は 'void(void *)throw()'であり、この型には 'operator()'はありません。 –
私の一部に「タイプo」だったhaha whoops。私はその逆を意味しました。 –