2015-06-22 136 views
0

我有一个转换模板,如果转换是安全的,它应该在指向类型的指针之间进行转换。这就像static_cast,但允许用户定义的类型。例如:2个复杂类型的表示,一个作为具有2个成员的实体/成像的结构,一个作为具有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); 
    } 
}; 

也就是说,我可以从复杂的*转换成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))); 
    } 
}; 

,并使用此一对夫妇基本类型(双,浮法,INT ...)的允许至少T->碱 - >ü这应该是足够的。

不幸的是,编译器似乎并没有找到SafePtrCast <复杂专业化,fftw_complex>

有没有更好的方式来处理这件事?我的模板有什么问题?

回答

0

怎么样使用特点:

template< typename T_Src, typename T_Dest, bool > 
struct Ptr2Ptr 

// allowed conversion 
template< typename T_Src, typename T_Dest> 
struct Ptr2Ptr<T_Src, T_Dest, true> 
{ 
    using Src = T_Src; 
    using Dest = T_Dest; 

    static Dest* conv(Src* data) const 
    { 
     return reinterpret_cast<Dest*>(data); 
    } 
}; 

template <typename T_Src, typename T_Dest> 
conv_trait 
{ 
    static const bool enabled = false ; 
} 
template< typename T_Src, typename T_Dest> 
struct SafePtrCast 
{ 
    T_Dest* 
    operator()(T_Src* data) const 
    { 
     return Ptr2Ptr<T_Src, T_Dest, conv_trait<T_Src, T_Dest>::value>::conv(data); 
    } 
} 

现在你可以在专门为conv_trais允许转换

template <class T> 
conv_trait<Complex, T *> 
{ 
    static const bool value = true ; 
} 
+0

'静态目的地* CONV(SRC *数据)const'静不可能是常量 –

+0

reinterpret_cast有它的缺陷,所以我想避免它,而是提供SafePtrCast的专门化(就像上面的Complex-> T) 也应该可以传递类似指针的类型(例如智能指针),但是在那里我无法使用static_cast 这就是为什么我基本上想检查,如果SafePtrCast的专业化T和T存在(T beeing一个整数类型) – Flamefire