Listing 4: Generalization via the preprocessor. Not very maintainable...

#if defined(PPHACK_USE_STD_STRING)
  typedef std::string               string_t;
#elif defined(PPHACK_USE_CSTRING)
  typedef CString                   string_t;
#elif defined(PPHACK_USE_CUSTOM_TYPE)
 #if !defined(PPHACK_CUSTOM_TYPE)
  #error Must defined PPHACK_CUSTOM_TYPE with custom type
 #endif /* !PPHACK_CUSTOM_TYPE */
  typedef PPHACK_CUSTOM_TYPE        string_t;
#else
 #error Must specify recognised PPHACK_USE_*** selector
#endif /* type */

  ...

  for(; begin != end; ++begin)
  {
    // Add the item to the result ...
    string_t const  &s(*begin);

#if defined(PPHACK_USE_STD_STRING)
    ListBox_AddString(hwndList, s.c_str());
#elif defined(PPHACK_USE_CSTRING)
    ListBox_AddString(hwndList, static_cast<char const *>(s));
#elif defined(PPHACK_USE_CUSTOM_TYPE)
 #if !defined(PPHACK_ACCESS_CUSTOM_TYPE)
  #error Must defined PPHACK_ACCESS_CUSTOM_TYPE with custom type
 #endif /* !PPHACK_ACCESS_CUSTOM_TYPE */
    ListBox_AddString(hwndList, PPHACK_ACCESS_CUSTOM_TYPE(s));
#else
 #error Must specify recognised PPHACK_USE_*** selector
#endif /* type */
  }