2

シンタックス シュガーについては、 への参照を返したいのですthisが、継承されると、関数は子クラスの型を返す必要があります。

class base {
  T &operator!() { return *this; }
};
base b; b = !b;

class child : public base {};
child c; c = !c;

演算子のせいで、ポインタを返して dynamic_cast することはできません。参照でなければなりません。

それは可能ですか?decltype(*this)for T の使用は機能せず、どちらも機能しません (自動の場合、auto f()->decltype(*this)理由thisはわかりませんが)

Scala では、次のように記述できます。

template<typename T> class base {
  T &f() { return *this; }
};
class child : public base<child> {};

しかし、私の g++ はこれを受け入れません (それがバグなのか、仕様にないだけなのかわかりませんか?)

もちろん明示的な方法もありますが、C++11の機能を使えば回避できるのではないでしょうか?

class child : public base {
  child &operator!() { base::operator!(); return *this }
};
4

2 に答える 2

2

You can use the CRTP to do this if you're allowed to make base a template:

template <typename Derived> class Base {
protected:
    Derived& refToThis() {
        return *static_cast<Derived*>(this);
    }
};

Note the extra cast here. The reason this works is that if you have a class like this one:

class Subclass: public Base<Subclass> {
    /* ... */
};

Then if you call refToThis from inside that class, it will call the base class version. Since the class inherits from Base<Subclass>, the instantiated template for refToThis will be

    Subclass& refToThis() {
        return *static_cast<Subclass*>(this);
    }

This code is safe, because the this pointer does indeed point to a Subclass object. Moreover, the static_cast will ensure that the cast fails at compile-time if the derived class doesn't inherit from Base properly, as the pointer type won't be convertible.

The reason that the cast is necessary here is that if you just say

template <typename Derived> class Base {
protected:
    Derived& refToThis() {
        return *this;
    }
};

Then there is a type error in the program, since a Base by itself is not a Derived, and if you could convert a Base& into a Derived& without any checks you could break the type system.

That said... I wouldn't do this at all. Overloading operator! for this purpose makes the code less readable, and just writing *this is so idiomatic that hiding it will make your code much harder to understand. Using all of this template machinery to avoid something that's common C++ seems misguided. If you're doing something else before returning the reference that's fine, but this just doesn't seem like a good idea.

Hope this helps!

于 2012-02-13T17:49:08.693 に答える
0

これをしないでください。言語でそれを行う方法はすでにあります*whatever_pointer_you_want_to_use_this_crazy_operator_upon。言語で何かを行う新しい方法を作成すると、将来のメンテナーが混乱するだけです。ここで実際に達成しようとしていることは他にありますか?

于 2012-02-13T18:21:38.977 に答える