Search code examples
c++stringtemplatesstlstdstring

Is it possible to write one function for std::string and std::wstring?


I just wrote a simple utility function for std::string. Then I noticed that the function would look exactly the same if the std::string was a std::wstring or a std::u32string. Is it possible to use a template function here? I am not very familiar with templates, and std::string and std::wstring are templates themselves, which might be an issue.

template<class StdStringClass>
inline void removeOuterWhitespace(StdStringClass & strInOut)
{
  const unsigned int uiBegin = strInOut.find_first_not_of(" \t\n");

  if (uiBegin == StdStringClass::npos)
  {
    // the whole string is whitespace
    strInOut.clear();
    return;
  }

  const unsigned int uiEnd   = strInOut.find_last_not_of(" \t\n");
  strInOut = strInOut.substr(uiBegin, uiEnd - uiBegin + 1);
}

Is this a proper way to do it? Are there pitfalls with this idea. I am not talking about this function but the general concept of using a templated class StdStringClass and calling the usual std::string functions like find, replace, erase, etc.


Solution

  • Its a good Idea, But I'd build the template on top of std::basic_string rather then general StdStringclass

    template<class T>
    inline void removeOuterWhitespace(std::basic_string<T>& strInOut)
    {
      constexpr auto delim[] = {T(' '),T('\t'),T('\n'),T(0)};
      const auto uiBegin = strInOut.find_first_not_of(delim);
    
      if (uiBegin == std::basic_string<T>::npos)
      {
        // the whole string is whitespace
        strInOut.clear();
        return;
      }
    
      const auto  uiEnd   = strInOut.find_last_not_of(delim);
      strInOut = strInOut.substr(uiBegin, uiEnd - uiBegin + 1);
    }
    

    I would also ditch the MSDN-style "inout" notation in favro for simpler name like str. programmer will guess themselves that str is the result since it is passed as non-const reference and function returns void.

    also, I changed unsigned int to auto. all the standard C++ containers/strings return size_t when returning indexes. size_t might not be unsigned int. auto matches itself to the right return value.