You can put all your wchar_t
versions in a class template, say overloads
and their char
counter-parts in its specialization as shown below:
template<typename WideCharVersion>
struct overloads
{
void foo(wchar_t const * arg)
{
FooW(arg);
}
//more wchar_t functions
};
template<>
struct overloads<std::false_type>
{
void foo(char const * arg)
{
FooA(arg);
}
//more char functions
};
//a friendly alias!
template<typename T>
using is_wide_char = typename std::is_same<whar_t, T>::type;
And then you can use them as:
template<typename _TChar>
void foo(const _TChar* str)
{
overloads<is_wide_char<_TChar>>::foo(str);
}
Expression SFINAE makes it easy!
Other way is to use Expression SFINAE which does not require to you write anything like overloads
and does the same job with less code:
template<typename _TChar>
void foo(const _TChar* str)
{
invokeOne(fooA, fooW, str);
}
And then you can implement invokeOne
as:
template<typename F1, typename F2, typename ... Args>
auto invokeOne(F1 f1, F2 f2, Args && ... args) -> decltype(f1(args...))
{
return f1(args...);
}
template<typename F1, typename F2, typename ... Args>
auto invokeOne(F1 f1, F2 f2, Args && ... args) -> decltype(f2(args...))
{
return f2(args...);
}
Have a look at the online demo.
In this approach, you don't have to add the overloads to the overloads
class template and to its specialization. Instead you just pass them as arguments to invokeOne
which calls the right overload for you.
Hope that helps.