实施 `to_xstring()` 以联合 `to_string()` 和 `to_wstring()`

Implement `to_xstring()` to unite `to_string()` and `to_wstring()`

由于 to_string()to_wstring() 的名称不同,因此几乎不可能在通用函数中使用它们。所以,我打算将它们与以下内容结合起来:

template <typename CharT, typename T>
auto to_xstring(const T& x);

问题是如何简洁的实现这样一个功能模板

我当前的实现有些笨拙(甚至有一个 detail 命名空间)。由于 C++ 不允许函数模板的部分特化,我将函数模板分派到可以部分特化的结构。我正在寻找更好的实现方式。

namespace detail {

template <typename>
struct to_xstring_helper;

template <>
struct to_xstring_helper<char> {
  template <typename T>
  static std::string invoke(const T& x) {
    // explicitly pulls in `std` in case `T` is not a class type
    using std::to_string;
    return to_string(x);
  }
};

template <>
struct to_xstring_helper<wchar_t> {
  template <typename T>
  static std::wstring invoke(const T& x) {
    // explicitly pulls in `std` in case `T` is not a class type
    using std::to_wstring;
    return to_wstring(x);
  }
};

} // namespace detail

/// Calls either `to_string(x)` or `to_wstring(x)` based on `CharT`. Lookups in
/// namespace `std` and that of `T` (by ADL). Given a uniform name, this
/// function template facilitates writing generic functions.
template <typename CharT, typename T>
auto to_xstring(const T& x) {
  return detail::to_xstring_helper<CharT>::invoke(x);
}

您可以在没有模板结构和偏特化的情况下使用静态分派,例如:

namespace detail {

  template<typename T>
  std::string to_string_helper_impl(const T& x, char) {
    using std::to_string;
    return to_string(x);
  }

  template <typename T>
  static std::wstring to_string_helper_impl(const T& x, wchar_t) {
    using std::to_wstring;
    return to_wstring(x);
  }

}

template <typename CharT, typename T>
auto to_xstring(const T& x) {
  return detail::to_string_helper_impl(x, CharT{});
}

您可以使用 SFINAE for this, no? E.g., using std::enable_if:

template <typename CharT, typename T>                                                                                                                                                                    
typename std::enable_if<std::is_same<CharT, char>::value, std::string>::type 
    to_xstring(const T &t)
{
    return std::to_string(t);
}


template <typename CharT, typename T>
typename std::enable_if<!std::is_same<CharT, char>::value, std::wstring>::type 
    to_xstring(const T &t)
{
    return std::to_wstring(t);
}