Функция шаблона для преобразования std :: string в std :: wstring и vice_versa с проверкой времени компиляции - PullRequest
0 голосов
/ 10 июля 2020

У меня есть следующие функции:

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

Спасибо.

1 Ответ

2 голосов
/ 10 июля 2020

Не особо элегантно ... но я полагаю, вы можете написать что-то вроде

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

Но вы уверены вам нужна одна функция, а не две перегруженные функции?

...