7

重複の可能性:
const および非 const のゲッターを複製するためのエレガントなソリューション?

次のように、const にオーバーロードされた memberfunction を持つ c++ クラスがあるとします。

        Type*  DoSomething();
const   Type*  DoSomething() const;

これがより大きく、より複雑なメンバーである場合、同じコードを 2 回記述する必要がないようにするにはどうすればよいでしょうか? const 関数から非 const 関数を呼び出すことはできません。また、const 以外のバージョンから const バージョンを呼び出すと、const ポインターが生成され、const 以外にキャストする必要があります (少し匂いがします)。

4

3 に答える 3

8

次のように、テンプレートの静的メンバー関数に委任できます。

class Widget
{
    Type member;

    template<typename Result, typename T>
    static Result DoSomethingImpl(T This)
    {
        // all the complexity sits here, calculating offsets into an array, etc
        return &This->member;
    }

public:
            Type*  DoSomething() { return DoSomethingImpl<Type*>(this); }
    const   Type*  DoSomething() const { return DoSomethingImpl<const Type*>(this); }
};

C++11 では、次のようにして、推論されないテンプレート引数を取り除くことさえできます。

static auto DoSomethingImpl(T This) -> decltype(This->member)
于 2012-07-25T18:08:39.873 に答える
1

クラスの const 属性を使用して 1 回実行し、2 回目に実行するには、次を使用できますconst_cast

class Foo
{
          Type*  DoSomething()
  {
    // Lots of stuff
  }
  const   Type*  DoSomething() const
  {
    return const_cast<Foo*>(this)->DoSomething();
  }
}
于 2012-07-25T18:13:08.250 に答える
1

テンプレート メソッドパターンを使用して、それらから共通コードを抽出します。例えば。

inline const T* prev(size_t i) const
{
    return &FBuffer[ AdjustIndex(i) ];
}

inline T* prev(size_t i)
{
    return &FBuffer[ AdjustIndex(i) ];
}

inline size_t AdjustIndex( size_t i ) const
{
    return Math::ModInt( static_cast<int>( FHead ) - 1 - i, static_cast<int>( FBuffer.size() ) );
}

この手法は多くの場合に適用できます (ただし、すべての場合ではありません。つまり、動作が大幅に異なる場合)。

于 2012-07-25T18:14:29.147 に答える