web-dev-qa-db-ja.com

テンプレート関数の引数としてのstd :: vector

引数としてstd :: vector参照を使用するクラスメソッドを作成し、さまざまなタイプのデータで使用したいです。

関数は次のようになります。

void some_function(const std::vector & vect){ //do something with vector }

そして、私は例えばでそれを使いたい:

std::vector<int> v1;
some_function(v1);
std::vector<string> v2;
some_function(v2);

自分の主張を明確にしたいと思います。そのようなテンプレートメソッドを作成する必要がありますか?

template<class T>
void some_function(std::vector<T> & vect){}

または別の方法でそれを行うことができますか?必要に応じて、クラスでそのメソッドを作成する方法を教えてください。

手伝ってくれてありがとう!

18
Prettygeek

template関数が_std::vector_を_const&_で受け入れるための正しい方法は次のとおりです。

_template<typename T, typename A>
void some_func( std::vector<T,A> const& vec ) {
}
_

2番目の引数は「アロケーター」であり、_std::vector_の高度な使用法ではデフォルトの引数ではありません。 _std::vector<T>_を受け入れるだけの場合、_some_func_は、代替アロケーターを使用して_std::vector_ sを拒否します。

さて、これにアプローチする他の方法があり、それをすぐにリストします。コスト:ベネフィット比の減少でそれらをリストします-上記の1つはおそらくあなたが望むものであり、次のものはおそらく有用です、その後、私は検討する価値がほとんどない過剰に設計されたケースに分岐します(しかし有用かもしれません場合によっては)。

_T&&_で任意のタイプTを受け入れてから、_typename std::remove_reference<T>::type_が_std::vector_の一種であるかどうかを判別するためにテストできます。これにより、着信_std::vector_の「完全な転送」が可能になります。また、テストに使用する述語を変更して、ほとんどの場合_std::vector_:以外のものを受け入れるようにすることもできます。ほとんどの場合、_const&_から_std::vector_には、おそらく任意のランダムアクセスコンテナが必要です。

とんでもない方法は、2段階の機能を実行することです。 2番目のステップでは、固定型Tに対してSFINAEを使用して型消去されたランダムアクセス範囲ビュー(またはランダムアクセスが不要な場合は範囲​​ビュー)を使用して、着信オブジェクトに互換性があることを確認します。渡された型のコンテナ型で、SFINAEコンテキストの2番目のステップを呼び出します(auto some_func(...)->decltype(...))。

連続したTsのランダムアクセス範囲ビューに対する_std::vector<T> const&_の型消去は多くの機能を失うことはないため、関数の本体が_std::vector<T> const&_に対してまったく同じであることを保証できるという利点があります。および_T[n]_および_std::array<T,n>_の場合。

特に必要な定型文にとっては、大きな利点ではありません。

c ++ 2 は、上記のマルチステップSFINAEがいくつかのrequire節に折りたたまれるので、これをはるかに簡単にすることができます。