namespace details{
template<template<class...>class Z,class,class...Ts>
struct can_apply:std::false_type{};
template<template<class...>class Z,class...Ts>
struct can_apply<Z,std::void_t<Z<Ts...>>,Ts...>:std::true_type{};
}
template<template<class...>class Z,class...Ts>
using can_apply=details::can_apply<Z,void,Ts...>;
Это проверяет, может ли шаблон применяться к некоторым типам.
namespace strcmp{
bool eq(const char*lhs, const char*rhs){/* body */}
}
template<class L, class R>
using str_eq_r=decltype(strcmp::eq(std::declval<L>(),std::declval<R>()));
template<class L, class R>
using can_str_eq=can_apply<str_eq_r,L,R>;
can_str_eq
является truthy тогда и только тогда мы можем назвать stdcmp::eq
на нем.
namespace details {
bool eq(const char* lhs, const char* rhs, std::true_type){
return strcmp::eq(lhs,rhs);
}
template<class L,class R>
bool eq(L const& l, R const&r,std::false_type){
return l==r;
}
}
template<class L,class R>
bool eq(L const& l, R const&r){
return details::eq(l,r,can_str_eq<L const&,R const&>{});;
}
Мы могли бы также использовать static_if
трюк, чтобы сделать это рядный, если вам нравится:
template<class L,class R>
bool eq(L const& l, R const&r){
return static_if<can_str_eq>(l, r)(
strcmp::eq,
[](auto&& l, auto&& r){return l==r;}
);
}
После написания static_if
:
template<class...Ts>
auto functor(Ts...ts){
return [=](auto&& f){
return f(ts...);
};
}
namespace details{
template<class Functor>
auto switcher(std::true_type, Functor functor){
return [=](auto&& t, auto&&){
return functor(t);
};
}
template<class Functor>
auto switcher(std::false_type, Functor functor){
return [=](auto&&, auto&& f){
return functor(f);
};
}
}
template<template<class...>class test, class...Ts>
auto static_if(Ts...ts){
return details::switcher(
test<Ts...>{},
functor(ts...)
);
}
сейчас, каковы шансы, что работает ? (Написано на телефоне, еще не составлено) Также не оптимально: много идеальной пересылки, некоторые из которых требуют делампинга.
Ум, почему бы не просто перегрузить два аргумента 'const char *'? – Brian
@Brian вызов с '' 'char *' '' и '' 'const char *' '' не делает трюк, если у меня есть перегрузка только с 2 '' 'const char *' '' - тогда шаблон получает вызов – onqtam
Рассмотрите возможность использования 'operator ==' – stackptr