有寫過vtk的人應該都用過vtkSmartPointer
而它初始化的方法就像

//member variable
vtkSmartPointer<vtkImageData> m_idata;
//on member funtion
m_idata = vtkSmartPointer<vtkImageData>::New();
m_idata->Initialize();

這樣又清楚又長,因為我為了縮短給他作了一個巨集:
#define VTK_SMART_POINTER(x)  typedef vtkSmartPointer< x >    x##_Sptr;
這樣只要寫

//member variable
vtkImageData_Sptr m_idata;
//on member funtion
m_idata = vtkSmartPointer<vtkImageData>::New();
m_idata ->Initialize();

可是還是太長了,
我想要這樣寫

//member variable
vtkImageData_Sptr m_idata;
//on member funtion
m_idata = vtkSmartNew;

運用最時尚的template技術就可以不輕易的達到喔~

以下是實作
//判斷有沒有Initialize這個函數
template <typename T, typename U>
class has_member_Initialize_tester
{
private:
    template <U> struct helper;
    template <typename T> static char check(helper<&T::Initialize> *);
    template <typename T> static char (&check(...))[2];
public:    
    enum { value = (sizeof(check<T>(0)) == sizeof(char)) };
};
//有的話value=1

//如果傳入1的話就表示有Initialize函數就執行一下吧
template <char Doit, class T>
struct static_Check_To_Initialize
{
    static void Do(T& ic){ic;}
};
template<class T>
struct static_Check_To_Initialize<1, T>
{
    static void Do(T& ic){ic->Initialize();}
};

static struct
{
    template <class T>
    operator vtkSmartPointer<T>()
    {
        vtkSmartPointer<T> ptr = vtkSmartPointer<T>::New();
        static_Check_To_Initialize
            <
                has_member_Initialize_tester< T, void (T::*)()>::value,
                vtkSmartPointer<T>
            >::Do(ptr);
        return ptr;
    }
}vtkSmartNew;
重載回傳值運算子來達成自動回傳需要值的目的。




讓地獄深紅的天亮 發表在 痞客邦 PIXNET 留言(0) 人氣()