私はlibffiを使用していて、std::function
(つまり、リターンタイプ( )と各引数タイプ()を対応するlibffiタイプclass Func<Ret (Args...)> { /* ... */};
に変換したい)と同様のテンプレートを使用してクラスを作成しました(これまでのところ、これを参照してください)。私はこれを思いついた:Ret
Args
// Member function of 'Func' class
Prepare(void)
{
// This vector holds all the type structures
std::vector<ffi_type*> argumentTypes{ GetFFIType<Args>()... };
ffi_type * returnType = GetFFIType<Ret>();
// Rest of the code below
// ....
}
GetFFIType関数が次のように実装されている場合:
template <typename T>
ffi_type * GetFFIType(void)
{
// We will check for any kind of pointer types
if(std::is_pointer<T>::value || std::is_array<T>::value ||
std::is_reference<T>::value || std::is_function<T>::value)
return &ffi_type_pointer;
if(std::is_enum<T>::value)
//return GetFFIType<std::underlying_type<T>::type>();
{
// Since the size of the enum may vary, we will identify the size
if(sizeof(T) == ffi_type_schar.size) return std::is_unsigned<T>::value ? &ffi_type_uchar : &ffi_type_schar;
if(sizeof(T) == ffi_type_sshort.size) return std::is_unsigned<T>::value ? &ffi_type_ushort : &ffi_type_sshort;
if(sizeof(T) == ffi_type_sint.size) return std::is_unsigned<T>::value ? &ffi_type_uint : &ffi_type_sint;
if(sizeof(T) == ffi_type_slong.size) return std::is_unsigned<T>::value ? &ffi_type_ulong : &ffi_type_slong;
}
assert(false && "cannot identify type");
}
// These are all of our specializations
template <> ffi_type * GetFFIType<void>(void) { return &ffi_type_void; }
template <> ffi_type * GetFFIType<byte>(void) { return &ffi_type_uchar; }
template <> ffi_type * GetFFIType<char>(void) { return &ffi_type_schar; }
template <> ffi_type * GetFFIType<ushort>(void) { return &ffi_type_ushort; }
template <> ffi_type * GetFFIType<short>(void) { return &ffi_type_sshort; }
template <> ffi_type * GetFFIType<uint>(void) { return &ffi_type_uint; }
template <> ffi_type * GetFFIType<int>(void) { return &ffi_type_sint; }
template <> ffi_type * GetFFIType<ulong>(void) { return &ffi_type_ulong; }
template <> ffi_type * GetFFIType<long>(void) { return &ffi_type_slong; }
template <> ffi_type * GetFFIType<float>(void) { return &ffi_type_float; }
template <> ffi_type * GetFFIType<double>(void) { return &ffi_type_double; }
template <> ffi_type * GetFFIType<long double>(void) { return &ffi_type_longdouble; }
これは機能しますが、明らかに改善の余地があります。タイプが無効な場合(つまり、クラスまたは構造)、コンパイル時に識別されません(代わりにを使用してランタイムエラーが発生しますassert
)。これを回避し、コンパイル中に型が有効(プリミティブ型)であるかどうかをこの関数に判断させるにはどうすればよいですか?
また、sの場合に基になるタイプを識別する方法も嫌いですenum
。std::underlying_type<T>
代わりに(コードでコメントアウトされている)使用したいのですが、タイプがたとえばvoidポインター( type_traits:1762:38: error: ‘void*’ is not an enumeration type
)の場合、コンパイルエラーが発生します。
私はこの動作を使用して達成しようとしましstd::enable_if
たが、成功しませんでした...少しあいまいに聞こえた場合に備えて、何かを説明する必要があるかどうか教えてください!
概要:GetFFIType関数を取得して、コンパイル中にすべてを判別したいのですが、関数はプリミティブ型のみをサポートする必要があります(より詳細なリファレンスについては、これを参照してください)。
編集:タイトルについて申し訳ありませんが、これ以上のことは思い浮かびませんでした:(