Listing 4 Policy-driven design of PopulateHelper
class PopulateHelper { // simple, because the interfaces for adding strings between // the two controls are orthogonal template <typename T> void fill(T &ctrl, std::vector<std::string> &strs) { ctrl.ResetContent(); for (int ii=0; ii<strs.size(); ++ii) ctrl.AddString(strs[ii]); } // a place-holder template <typename T> struct GetTextFromCtrlPolicy {}; // specialization for the CComboBox control template <> struct GetTextFromCtrlPolicy<CComboBox> { static CString GetText(CComboBox &ctrl, int iIndex) { CString retStr; ctrl.GetLBText(iIndex, retStr); return retStr; } }; // specialization for the CListBox control template <> struct GetTextFromCtrlPolicy<CListBox> { static CString GetText(CListBox &ctrl, int iIndex) { CString retStr; ctrl.GetText(iIndex, retStr); return retStr; } }; // now it doesn't matter if this method is specialized on CComboBox // or CListBox, the correct call is resolved through the // GetTextFromCtrlPolicy struct. template <typename T> CString getData(T &ctrl, int iIndex) { CString data; data = GetTextFromCtrlPolicy<T>::GetText(ctrl, iIndex); return data; } };