我有一个转换模板,如果转换是安全的,它应该在指向类型的指针之间进行转换。这类似于 static_cast 但允许用户定义类型。
示例:复杂类型的 2 种表示形式,一种作为具有 2 个用于 real/imag 的成员的结构,一种作为具有 2 个元素的数组。将指向其中一个的指针转换为指向另一个的指针是安全的。
我的模板如下所示:
template< typename T_Src, typename T_Dest, typename T_SFINAE = void >
struct SafePtrCast;
template< typename T >
struct SafePtrCast< Complex<T>*, T* >
{
T*
operator()(Complex<T>* data)
{
return &data->real;
}
};
template< typename T >
struct SafePtrCast< T*, fftw_complex* >
:Ptr2Ptr<T, fftw_complex>{};
template< typename T_Src, typename T_Dest = T_Src >
struct Ptr2Ptr
{
using Src = T_Src;
using Dest = T_Dest;
Dest*
operator()(Src* data) const
{
return reinterpret_cast<Dest*>(data);
}
};
也就是说,我可以从 Complex* 转换为 T*,从 T* 转换为 fftw_complex*。从语义上讲,这意味着我也可以从 Complex* 转换为 fftw_complex*。
但是我怎么能告诉编译器,这没关系?我试过:
template< typename T_Src, typename T_Dest >
struct SafePtrCast<
T_Src,
T_Dest,
void_t< std::result_of_t<
SafePtrCast<
std::result_of_t<
SafePtrCast<T_Src, double* >
>,
T_Dest
>
> >
>{
using Conv1 = SafePtrCast< T_Src, double* >;
using Conv2 = SafePtrCast< double*, T_Dest >;
T_Dest
operator()(T_Src&& data) const
{
return Conv2(Conv1(std::forward<T_Src>(data)));
}
};
并将它与几个基本类型(double、float、int ...)一起使用,以至少允许 T->base->U 这应该足够了。
不幸的是,编译器似乎没有找到 SafePtrCast< Complex , fftw_complex >的特化
有没有更好的方法来处理这个问题?我的模板有什么问题?