有寫過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;
重載回傳值運算子來達成自動回傳需要值的目的。
留言列表