2009年1月30日金曜日

コンテナクラステンプレートにポインタを格納するときの型の問題

こんなの。


template <typename T1>
class BaseContainer
{
public:
  iterator find(const T1& t1);
};

template <typename T2>
class ElementContainer
{
public:
  iterator find(const T2& t2)
  {
    return iterator(m_entity.find(&t2));
      // ここでconst外しになる。
  }
private:
  BaseContainer<T2*> m_entity;
};


上記の例ではT1がT2*と指定されるので、BaseContainer::find()の引数の型はT2* const &になる。それに対して&t2の型はT2 const*である。言い換えるとBaseContainer::find()の引数はポインタ値にconstがついており、ポインタが参照している領域にはconstがついてないが、&t2はポインタが参照している領域にconstがついている。したがってポインタからconstを外さないとBaseContainer::find()に渡せない。

BaseContainerは他の箇所でも使うので、find()の引数の型を変えたくはない。またElementContainerは外部仕様的にはポインタを意識させたくない。

とりあえずfind()を呼び出すときに&const_cast<T2&>(t2)として逃げたけど、本当はどう書くとよいのだろう?

2 件のコメント:

  1. BaseContainer<const T*> m_entity;
    でいいんじゃないでしょうか。

    返信削除
  2. すみません、省略していたのですが ElementContainer を普通のコンテナとして作ろうとすると、非constな操作もさせたくなると思うのです。たとえば T2& operator[](std::size_t index) みたいな。
    BaseContainer<const T*> m_entity;
    にすると、find()をクリアできる代わりにoperator[]()にてconst_castが必要になると思います。

    返信削除