通过编译时检查将 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 {};

现在我对如何以一种非常严格的方式做到这一点感到困惑:如果 Tstd::stringU 必须是 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 个重载函数吗?