1

template<class CRTP> Base現在、基本クラスと派生クラスDerived1 : public Base<Derived1>を使用してCRTPを実装していDerived2 : public Base<Derived2>ます...

算術演算子は で定義されており、 a に a を追加できますが、 aに a を追加できないことを意味するBaseタイプです。CRTP Base<CRTP>::operator+(const CRTP& rhs)Derived1Derived1Derived2Derived1

さらに、 を返す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

最後の2行によると:

  • ユーザーのミスを防ぎます
  • しかし、彼が本当にこの操作をしたいのであれば、派生型を基本型に「キャスト」することができ、それは機能します。

これを行う必要があるのは、そのような演算子を定義することだけです:

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型の場合

そのようなものは存在しますか?他の解決策を考えていますか?

どうもありがとうございました !

4

1 に答える 1

2

/ * SOMETHING * /は、次を使用して簡単にアーカイブできます。

  1. std::is_sameDerivedおよび
  2. Baseの「true」部分のヘルパークラス

ヘルパークラスは、クラスが正確に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()


例: 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
}
于 2012-08-18T19:57:42.577 に答える