实施 `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);
}
由于 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);
}