У меня проблема с перегрузкой некоторых операторов.
В частности, у меня есть шаблон, interface_mixin<T>
, который имеет традиционную настройку CRTP, т.е. Derived : public interface_mixin<Derived>
.
Теперь мне нужно перегрузить операторы, на одной стороне которых находится объект, а на другой стороне - шаблон, то есть:
template<typename T, typename Derived> ... operator..
(T t, const interface_mixin<Derived>& d) {
...
}
template<typename T, typename Derived> ... operator..
(const interface_mixin<T>& t, Derived d) {
...
}
template<typename T, typename Derived> ... operator..
(const interface_mixin<T>& t, const interface_mixin<Derived>& d) {
...
}
Однако мой компилятор (VS2010) не примет это, вызывая неоднозначную перегрузку. Как я могу убедить его принять эти перегрузки?
Прямо сейчас я пытаюсь использовать SFINAE, чтобы попытаться устранить другие перегрузки. Но даже если логика кажется хорошей, компилятор выбирает неправильную перегрузку.
template<typename T, typename Derived>
typename std::enable_if<
!std::is_base_of<
interface_mixin<T>,
T
>::value,
and<
equality_rule<T>,
Derived
>
>::type operator>>(T t, const interface_mixin<Derived>& d) {
return and<equality_rule<T>, Derived>(equality_rule<T>(std::move(t)), d.crtp_cast());
}
template<typename T, typename Derived>
typename std::enable_if<
!std::is_base_of<
interface_mixin<Derived>,
Derived
>::value,
and<
T,
equality_rule<Derived>
>
>::type operator>>(const interface_mixin<T>& t, Derived d) {
return and<T, equality_rule<Derived>>(t.crtp_cast(), equality_rule<Derived>(std::move(d)));
}
template<typename T, typename Derived> and<T, Derived> operator>>(const interface_mixin<T>& t, const interface_mixin<Derived>& d) {
return and<T, Derived>(t.crtp_cast(), d.crtp_cast());
}
Однако VS выбирает неправильную перегрузку, и логика не будет иметь смысла, когда выбрана неправильная перегрузка.