Перегрузка при наследовании с CRTP и другими шаблонами - PullRequest
1 голос
/ 07 декабря 2011

У меня проблема с перегрузкой некоторых операторов.

В частности, у меня есть шаблон, 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 выбирает неправильную перегрузку, и логика не будет иметь смысла, когда выбрана неправильная перегрузка.

1 Ответ

1 голос
/ 08 декабря 2011

Первая часть вашего вопроса отличается от второй, вы не указываете тип возвращаемого значения для тела функции.
Если тип возвращаемого значения void - этот код работает с моим компилятором MSVC2010:

#include <iostream>

template<class T> struct interface_mixin {};

template<typename T, typename Derived>
typename std::enable_if<!std::is_base_of<interface_mixin<T>, T>::value, void>::type
operator>>(T t, const interface_mixin<Derived>& d) { std::cout << "1\n"; }

template<typename Derived, typename T>
typename std::enable_if<!std::is_base_of<interface_mixin<T>, T>::value, void>::type
operator>>(const interface_mixin<Derived>& d, T t) { std::cout << "2\n"; }

template<typename DerivedL, typename DerivedR>
void
operator>>(const interface_mixin<DerivedL>& t, const interface_mixin<DerivedR>& d)
{ std::cout << "3\n"; }

struct Foo : interface_mixin<Foo> {};
struct Bar : interface_mixin<Bar> {};

int main()
{
    Foo f;
    Bar b;

    1 >> f;
    f >> 1;
    f >> b;
}

Я не знаю, связана ли проблема с типом возврата или чем-то другим, но enable_if должен решить эту проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...