2

テンプレートに stl アルゴリズム remove_if を適用しようとしたところ、問題が発生しました。どんな助けでも大歓迎です!

template <class T> bool flag_delete(pair<T,int> a) {return (a.second == 1);}

template <class T> void fun_delete_by_flag(vector<T> &vec_data, ivec &vec_flag)
{
    int n = vec_data.size();
    vector< pair<T,int> > vec;
    vec.resize(n);
    for ( int i = 0; i < n; i += 1 ) {
        vec[i].first = vec_data[i];
        vec[i].second = vec_flag[i];
    }
    typename vector< pair<T,int> >::iterator it;
    it = remove_if(vec.begin(), vec.end(), flag_delete);
    n = vec.size();
    vec_data.resize(n);
    for ( int i = 0; i < n; i += 1 ) {
        vec_data[i] = vec[i].first;
    }
    return;
}

以下のメッセージを受け取りました。

guess_algo.h: In function ‘void fun_delete_by_flag(std::vector<T>&, ivec&) [with T = std::pair<int, std::basic_string<char> >, ivec = std::vector<int>]’:
user_time.h:63:34:   instantiated from here
guess_algo.h:61:2: error: no matching function for call to ‘remove_if(std::vector<std::pair<std::pair<int, std::basic_string<char> >, int>, std::allocator<std::pair<std::pair<int, std::basic_string<char> >, int> > >::iterator, std::vector<std::pair<std::pair<int, std::basic_string<char> >, int>, std::allocator<std::pair<std::pair<int, std::basic_string<char> >, int> > >::iterator, <unresolved overloaded function type>)’
4

3 に答える 3

3

remove_ifの呼び出しを次のように変更する必要があります。

it = remove_if(vec.begin(), vec.end(), flag_delete<T>);

すなわち。<T>の末尾に を追加しflag_deleteます。これは、関数が に指定されたものと同じテンプレート パラメータを持つ必要があることを伝えていないためですfun_delete_by_flag。ここでのヒントは<unresolved overloaded function type>、エラー メッセージの最後にある (かなりよく隠されています) です。

于 2012-01-26T10:40:57.807 に答える
3

他の人が指摘したことに関係なく(テンプレートパラメータを指定する必要があります)、呼び出しがありませんstd::vector::erase(またはvec_data.resize()呼び出しが冗長です)。

std::remove_ifコンテナのサイズを縮小しません!

したがって、マークされた行を追加するか

auto it = remove_if(vec.begin(), vec.end(), flag_delete<T>);
vec.erase(it);        // <-- ADD THIS TO ACTUALLY REDUCE CONTAINER LENGTH
n = vec.size();
vec_data.resize(n);

または、少し書き直します。ベクトルの割り当てが標準に従って連続していることがわかれば、全体を次のように要約できます (c++0x のサポートを前提としています)。

template <class T> void simpler(vector<T> &vec_data, const ivec &vec_flag)
{
    T *begin = &vec_data.front();
    size_t newsize = std::distance(begin, 
            std::remove_if(
                begin, begin + vec_data.size(), [&] (T& el) 
                { 
                    return 1 == vec_flag[std::distance(begin, &el)]; 
                }));

    vec_data.resize(newsize);
}

ライブでご覧ください: http://ideone.com/S2WUC

編集元の関数も少しクリーンアップしました (注const&size_terasereserveおよびstd::make_pair):

template <class T> void fun_delete_by_flag(vector<T> &vec_data, const ivec &vec_flag)
{
    size_t n = vec_data.size();
    vector< pair<T,int> > vec;
    vec.reserve(n);
    for ( size_t i = 0; i < n; i += 1 ) 
        vec.push_back(std::make_pair(vec_data[i], vec_flag[i]));

    vec.erase(remove_if(vec.begin(), vec.end(), flag_delete<T>));

    n = vec.size();
    vec_data.resize(n);

    for ( size_t i = 0; i < n; i += 1 )
        vec_data[i] = vec[i].first;

    return;
}
于 2012-01-26T11:10:45.507 に答える
0

エラー メッセージの最初の行を確認してください。

guess_algo.h: In function ‘void fun_delete_by_flag(std::vector<T>&, ivec&) [with T = std::pair<int, std::basic_string<char> >, ivec = std::vector<int>]’:

これは、T がペア型であることを示しています。そして最後の行は、(最後に) 「未解決のオーバーロードされた関数型」を呼び出していることを示しています。つまり、関数 flag_delete で定義されているものとは異なるパラメーターを指定しています。

最初のエラーメッセージから、ペアを指定しています。タイプを確認してみてください。おそらく、T を別の文字に変更してください。

于 2012-01-26T10:47:23.333 に答える