通过编译时检查将 std::string 转换为 std::wstring 和 vice_versa 的模板函数
Template function to convert std::string in std::wstring and vice_versa with compile time checking
我有以下功能:
std::string convert(const std::wstring &str);
std::wstring convert(const std::string &str);
我想做这样的事情:
template<class T, class U> T convert(const U& u);
我创建了一些验证:
template<class T> struct is_string : public std::false_type {};
template<class T> struct is_string<std::basic_string<T>> : public std::true_type {};
现在我对如何以一种非常严格的方式做到这一点感到困惑:如果 T
是 std::string
,U
必须是 std::wstring
并且反之亦然。所有其他情况都不应编译。
有线索吗?
我的编译器是 C++11
谢谢。
不是特别优雅...不过我想你可以这样写
#include <type_traits>
#include <string>
template <typename T,
typename U = typename std::conditional<std::is_same<T, std::string>::value,
std::wstring,
std::string>::type>
typename std::enable_if<std::is_same<T, std::string>::value
|| std::is_same<T, std::wstring>::value, U>::type
convert (T const & s)
{ /* do something */ return {}; }
int main ()
{
auto ws = convert(std::string{});
auto s = convert(std::wstring{});
static_assert( std::is_same<decltype(ws), std::wstring>::value, "!" );
static_assert( std::is_same<decltype(s), std::string>::value, "!" );
}
或(可能更好)具有自定义类型特征
#include <type_traits>
#include <string>
template <typename>
struct swapString
{ };
template <>
struct swapString<std::string>
{ using type = std::wstring; };
template <>
struct swapString<std::wstring>
{ using type = std::string; };
template <typename T,
typename U = typename swapString<T>::type>
U convert (T const & s)
{ /* do something with s */ return {}; }
int main ()
{
auto ws = convert(std::string{});
auto s = convert(std::wstring{});
static_assert( std::is_same<decltype(ws), std::wstring>::value, "!" );
static_assert( std::is_same<decltype(s), std::string>::value, "!" );
}
但是你确定你想要一个函数而不是 2 个重载函数吗?
我有以下功能:
std::string convert(const std::wstring &str);
std::wstring convert(const std::string &str);
我想做这样的事情:
template<class T, class U> T convert(const U& u);
我创建了一些验证:
template<class T> struct is_string : public std::false_type {};
template<class T> struct is_string<std::basic_string<T>> : public std::true_type {};
现在我对如何以一种非常严格的方式做到这一点感到困惑:如果 T
是 std::string
,U
必须是 std::wstring
并且反之亦然。所有其他情况都不应编译。
有线索吗?
我的编译器是 C++11
谢谢。
不是特别优雅...不过我想你可以这样写
#include <type_traits>
#include <string>
template <typename T,
typename U = typename std::conditional<std::is_same<T, std::string>::value,
std::wstring,
std::string>::type>
typename std::enable_if<std::is_same<T, std::string>::value
|| std::is_same<T, std::wstring>::value, U>::type
convert (T const & s)
{ /* do something */ return {}; }
int main ()
{
auto ws = convert(std::string{});
auto s = convert(std::wstring{});
static_assert( std::is_same<decltype(ws), std::wstring>::value, "!" );
static_assert( std::is_same<decltype(s), std::string>::value, "!" );
}
或(可能更好)具有自定义类型特征
#include <type_traits>
#include <string>
template <typename>
struct swapString
{ };
template <>
struct swapString<std::string>
{ using type = std::wstring; };
template <>
struct swapString<std::wstring>
{ using type = std::string; };
template <typename T,
typename U = typename swapString<T>::type>
U convert (T const & s)
{ /* do something with s */ return {}; }
int main ()
{
auto ws = convert(std::string{});
auto s = convert(std::wstring{});
static_assert( std::is_same<decltype(ws), std::wstring>::value, "!" );
static_assert( std::is_same<decltype(s), std::string>::value, "!" );
}
但是你确定你想要一个函数而不是 2 个重载函数吗?