【问题标题】:enable_if allowing base class onlyenable_if 只允许基类
【发布时间】:2012-08-14 17:01:09
【问题描述】:

我目前正在使用基类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 类型

这样的事情存在吗?您有其他解决方案吗?

非常感谢!

【问题讨论】:

    标签: inheritance c++11 operator-overloading crtp enable-if


    【解决方案1】:

    /* SOMETHING */ 可以使用

    轻松归档
    1. std::is_same 用于 Derived 的“假”部分和
    2. Base 的“真实”部分的帮助类

    辅助类是判断一个类是否正好是Base&lt;?&gt;:

    template <typename> struct IsBase : std::false_type {};
    ...
    template <typename X> struct IsBase<Base<X>> : std::true_type {};
    

    然后我们可以在 /* SOMETHING */ 中填写:

    std::is_same<Other, Self>::value || IsBase<Other>::value
    

    请注意,这允许Derived1 + Derived2()。


    示例:http://ideone.com/OGt0Q

    #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
    }
    

    【讨论】:

      猜你喜欢
      • 2021-08-24
      • 2018-03-06
      • 1970-01-01
      • 1970-01-01
      • 2017-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多