1

私の仕事では多くのペアプログラミングを行っており、SINGLEタイプまたはその派生物のコンテナーのみを受け入れる関数を作成しましたが、同僚はコードレビューに失敗するのではないかと心配しています。より良い方法である:

これが署名です。Fruitクラスは、このスレッドのためだけにFruitに名前を変更した基本クラスです。

template <class Container>
typename enable_if<is_base_of<Fruit, typename remove_pointer<typename Container::value_type>::type>::value, void>::type
processFruits(container& fruits)
{
    //process the elements and change them if needed. thats why no const
}

それが何をするか:voidを返し、そのコンテナであり、コンテナ内のタイプがフルーツであるか、フルーツから派生している場合、関数を有効にします。ポインターの「タイプ」を知る必要があるため、std :: remove_pointerも使用しました(コンテナーにはポインターが含まれている可能性があります)。

これは意図したとおりにコンパイルおよび動作しますが、私が言ったように、それを行うための最良の方法はわかりません。冗長すぎるようで、コードレビューが途切れる可能性があります。

編集:これはテンプレート化されたクラスも受け入れます。コンテナである必要はありません。STLコンテナのみを受け入れるように制限する方法はありますか?

別のアイデアはありますか、それともそれがそうであるようにそれは大丈夫ですか?前もって感謝します。

4

1 に答える 1

1

読むのは少し恐ろしいです。

初心者にとっては、デフォルトのテンプレート引数を言って使用enable_if<B, void>できると言う必要はありません。enable_if<B>

あなたはそれを別々の部分に簡単に分割することができます:

template <class T>
  struct is_fruity
  : is_base_of<Fruit, T>
  { };

template <class Container, typename Value = typename Container::value_type>
  struct is_fruit_container
  : is_fruity<typename remove_pointer<Value>::type>>
  { };

template<class Container>
  typename enable_if<is_fruit_container<Container>::value>::type
  processFruits(Container& fruits)
  {
    //process the elements and change them if needed. thats why no const
  }

エイリアステンプレートをサポートするコンパイラがある場合は、さらに読みやすくすることができます。

template<typename Cond>
  using Require = typename enable_if<Cond::value>::type;

template<class Container>
  Require<is_fruit_container<Container>>
  processFruits(Container& fruits)
  {
    //process the elements and change them if needed. thats why no const
  }

これはテンプレート化されたクラスも受け入れます。コンテナである必要はありません。STLコンテナのみを受け入れるように制限する方法はありますか?

「テンプレート化されたクラス」の意味がわかりません。ネストされたvalue_type型の型のみを受け入れます。これは、そのような型から派生した型Fruitまたはそのような型へのポインタであり、テンプレートである必要はありません。「STLコンテナ」に限定するには、「STLコンテナ」を識別するためのトレイトを作成する必要がありますが、それを定義する必要があります。これを適切に行うには、、、メンバー、およびコンテナ要件begin()、、などで指定されたすべてのネストされたタイプをテストするトレイトが必要です。end()size()iteratorvalue_type

template<typename C, typename Chead, typename... Ctail>
struct static_and
{
  static const bool value = C::value && static_and<Chead, Ctail...>::value;
};

template<typename C>
struct static_and<C>
{
  static const bool value = C::value;
};

template<typename C>
struct is_container
: static_and<has_begin<C>, has_end<C>, has_iterator<C>, has_value_type<C> /* etc */>
{ };
于 2012-07-13T19:26:30.223 に答える