我目前正在用一个基类template<class CRTP> Base
和派生类Derived1 : public Base<Derived1>
,Derived2 : public Base<Derived2>
实现一些CRTP。
数学运算符是在Base
中定义的,其类型为CRTP Base<CRTP>::operator+(const CRTP& rhs)
,这意味着我们可以将Derived1
添加到Derived1
中,而不能将Derived2
添加到Derived1
中。
此外,我定义了操作符Base<CRTP>& Base<CRTP>::operator()()
,这意味着Derived1()
将返回Base<Derived1>&
。
我想知道是否有办法做到以下几点:
Derived1 = Derived1 + Derived1 : OK
Derived2 = Derived2 + Derived2 : OK
Derived1 = Derived1 + Derived2 : NOT OK
Derived1 = Derived1() + Derived2() : OK
根据最后两行:
我唯一需要做的就是定义一个这样的操作符:
template<class CRTP0, class = typename std::enable_if</* SOMETHING */>::type>
Base<CRTP> Base<CRTP>::operator+(const Base<CRTP0>& rhs)
在enable_if中,我想要的是:
true
:如果rhs是Base
类型的false
:如果rhs是Derived
类型有这样的东西存在吗?你有其他的解决方案吗?
非常感谢!
发布于 2012-08-18 11:57:42
/*某事*/可以很容易地使用
std::is_same
用于派生的“假”部分和助手类是用来确定一个类是否恰好是一个Base<?>
。
template <typename> struct IsBase : std::false_type {};
...
template <typename X> struct IsBase<Base<X>> : std::true_type {};
然后我们就可以填写这个/*了*/用:
std::is_same<Other, Self>::value || IsBase<Other>::value
请注意,这允许Derived1 + Derived2()
。
#include <type_traits>
template <typename> struct IsBase : std::false_type {};
template <typename Self>
struct Base {
Base& operator()() {
return *this;
};
template <typename Other,
typename = typename std::enable_if<std::is_same<Other, Self>::value
|| IsBase<Other>::value>::type>
Self operator+(const Other& other) const {
return static_cast<const Self&>(*this);
}
};
template <typename X> struct IsBase<Base<X>> : std::true_type {};
struct D1 : Base<D1> {};
struct D2 : Base<D2> {};
int main() {
D1 d1;
D2 d2;
d1 + d1; // ok
d2 + d2; // ok
d1() + d2(); // ok
d1 + d2; // error
}
https://stackoverflow.com/questions/12019463
复制相似问题