我在重载某些运算符时遇到了问题。
具体来说,我有一个模板,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/