简体   繁体   中英

Template function to convert std::string in std::wstring and vice_versa with compile time checking

I have the following functions:

std::string convert(const std::wstring &str);
std::wstring convert(const std::string &str);

Which I would like to do something like this:

template<class T, class U> T convert(const U& u);

I created some verification:

template<class T> struct is_string : public std::false_type {};
template<class T> struct is_string<std::basic_string<T>> : public std::true_type {};

And then now I'm confusing on how to do that in a really strict way: if T is std::string , U must be a std::wstring and vice-versa. All other cases shouldn't compile.

Any clue?

My compiler is on C++11

Thanks.

Not particularly elegant... but I suppose you can write something as follows

#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, "!" );
 }

or (maybe better) with a custom type traits

#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, "!" );
 }

But are you sure you want a single function and not 2 overloaded functions?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM