简体   繁体   English

使用CRTP和其他模板继承时重载

[英]Overloading on inheritance with CRTP and other templates

I've got a problem with overloading some operators. 我在重载一些运算符时遇到了问题。

Specifically, I have a template, interface_mixin<T> , which has the traditional CRTP setup, ie, Derived : public interface_mixin<Derived> . 具体来说,我有一个模板interface_mixin<T> ,它具有传统的CRTP设置,即Derived : public interface_mixin<Derived>

Now I need to overload operators on which side is an object, but the other side is a template, that is: 现在,我需要重载运算符,哪一边是一个对象,但另一边是一个模板,即:

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) {
    ... 
}

However, my compiler (VS2010) won't accept this, calling ambiguous overload. 但是,我的编译器(VS2010)不会接受此方法,从而导致歧义重载。 How can I convince it to accept these overloads? 我如何说服它接受这些超载?

Right now, I'm trying to use SFINAE to try to clear the other overloads. 现在,我正在尝试使用SFINAE尝试清除其他重载。 But even though the logic seems fine, the compiler picks the wrong overload. 但是,即使逻辑看起来不错,编译器也会选择错误的重载。

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());
}

However, VS is picking the wrong overload, and the logic won't make sense when the wrong overload is picked. 但是,VS选择了错误的重载,而选择了错误的重载时,逻辑将没有意义。

The first part of your question differs form second, you don't specify return type an function body there. 问题的第一部分与第二部分有所不同,您未在其中指定返回类型为函数体。
If return type is void - this code works with my MSVC2010 compiler: 如果返回类型为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;
}

I don't know if the problem is with return type or something other, but enable_if should solve this problem. 我不知道问题是否出在返回类型或其他方面,但是enable_if应该可以解决此问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM