Reputation: 116
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.
Upvotes: 0
Views: 289
Reputation: 66230
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?
Upvotes: 2