c++ - 使用 CRTP 和其他模板重载继承

标签 c++ visual-studio-2010 c++11

我在重载某些运算符时遇到了问题。

具体来说,我有一个模板,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());
}

However, VS is picking the wrong overload, and the logic won't make sense when the wrong overload is picked.

最佳答案

你的问题的第一部分与第二部分不同,你没有在那里指定函数体的返回类型。
如果返回类型是 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 应该可以解决这个问题。

关于c++ - 使用 CRTP 和其他模板重载继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8416711/

相关文章:

启用proguard时的java.lang.UnsatisfiedLinkError : No implementation found for java. lang.String

c# - 如何让 Intellisense 自动解决缺少的 Using 指令

visual-studio-2010 - 禁用 VS 2010 格式粘贴 Razor 但不是 c#

c++ - 可以在模板参数中使用 decltype 吗?

Ms Visual Studio : "Windows has triggered a breakpoint in javaw.exe" 上的 C++ 错误

c++ - boost::chrono 纳秒 Windows 7

asp.net - 如何在 Visual Studio 2010 中设置 Umbraco cms?

c++ - 在模板类中的自动类型推断变量上调用模板函数

c++ - 使用空大括号初始化程序 : pointer or reference? 的重载分辨率

c++ - 如何在verilog模块上运行SPECfp基准测试?