2

ベクターを反復処理して、要素がベクターか文字列かを確認したいと思います。また、さまざまなベクトルを関数に渡す方法も必要です。このようなもの:

using namespace std;
string toCustomString(<some vector> vec) {
    string ret = "";
    for(size_t i = 0; i < vec.length(); ++i) 
        if (vec[i] == %vector%)
            ret += toCustomString(vec[i]);
        else //if type of vec[i] is string
            ret += "foo"+vec[i]+"bar";
    }
    return ret;
}
  • まず、vec[i] が std::vector であるかどうかを正しくチェックする方法を知る必要があります。

  • 次に、関数があらゆる種類の (多次元) ベクトルを受け入れるようにパラメーターを定義する方法を知る必要があります。

4

3 に答える 3

6

std::vectorには 1 つの型のみを含めることができます。これはTinstd::vector<T>であり、 member でアクセスできますvalue_type

おそらく探しているのは、テンプレートの特殊化です。

template<typename T>
string toCustomString(std::vector<T> vec) {
    // general case
}

template<>
string toCustomString<std::string>(std::vector<std::string> vec) {
    // strings
}

(すべてのベクトルに対して部分的に特殊化する場合は、構造体に持ち上げる必要があります)

本当に文字列とベクトルの両方をベクトルに格納したい場合は、Boost.Variant と Boost.Any を見てください。

于 2012-10-18T14:55:27.603 に答える
2

通常、<some vector> vecタイプは or のいずれ vector<string> vector<vector<string>>です。

変数を宣言するには、その型が必要です。また、その型は格納するものを正確に指定します。

これで、次のように、 Boost.Variant (または独自の判別共用体をロール)を使用してこれを回避できます。

typedef boost::variant<std::string, std::vector<std::string>> Vec_of_StringOrVec;

しかし、Dirk Holsopple は、これが慣用的な C++ ではないことを正しく示しており、別のアプローチを探したほうがよいかもしれません。

于 2012-10-18T14:59:54.743 に答える
0

誰もが言うように、C++ のベクトルは 1 つの型しか保持しません。各要素の型を順番にチェックする必要はありませんし、意味もありません。それを行う方法がないからです。代わりに行うことは、引数の型で関数をオーバーロードすることです。このようなもの:

string toCustomString(const string &str) {
    return "foo" +str + "bar";
}

template <typename T>
string toCustomString(const std::vector<T> &vec) {
    string ret;
    for(size_t i = 0; i < vec.size(); ++i) 
        ret += toCustomString(vec[i]);
    return ret;
}

ここで、誰かが avector<string>を渡すtoCustomStringと、呼び出しはオーバーロードtoCustomString(vec[i])を選択しますtoCustomString(const string &str)

誰かが avector<int>を渡すと、 toCustomString(現在)toCustomString(int)オーバーロード[*] がないため、コードはコンパイルされません。

誰かが avector<vector<string>>をに渡すと、toCustomString次にa が渡されます。上記を参照してください。toCustomString(vec[i])vector<string>

3 つのケースすべてで、異なる toCustomString関数が呼び出されます。最初のケースは で、これは3 番目のケースとは異なるテンプレートtoCustomString<string>(const vector<string>&)のインスタンス化です。中間のケースは をインスタンス化しようとしますが、知っているどの関数とも一致しないため失敗します。toCustomStringtoCustomString<vector<string>>(const vector<vector<string>>&)toCustomString<int>toCustomString(v[i])

これらはすべてコンパイル時に決定されます。テンプレートのポイントは、それらの間に特定の違いがある複数の関数 (またはクラス) を作成することです。この場合の違いは、渡されるベクトルのタイプです。

[*] これは、3 番目のオプションではなくベクトルまたはvec[i]文字列でなければならないというあなたの主張と一致しているようです。たとえば、 a の戻り値を空にしたい場合は、キャッチオール テンプレートを追加できます。vector<something_else>

template <typename T> 
string toCustomString(const T &) { 
    return string(); 
}

もちろん、処理したい他の型にオーバーロードを追加することもできます。

于 2012-10-18T15:14:29.170 に答える