2

コードは次のとおりです。

#include <vector>
#include <algorithm>
#include <string>
#include <map>
#include <iostream>
using namespace std;

map<string, int> g_map;
void read_item(const pair<string, int>& p) {
   g_map[p.first] += p.second;
}

void myprint(std::pair<const string, int> ci) {
   cout << "first : " << ci.first << "seconde : " << ci.second << endl;
}

void myprint(int ci) {
   cout << ci << endl;
}

int main()
{
    string a = string("nail");
    string b = string("hammer");
    read_item(make_pair(a, 100));
    read_item(make_pair(b, 2));
    read_item(make_pair(b, 10));
    read_item(make_pair(a, 200));

    std::for_each(g_map.begin(), g_map.end(), myprint); // can't find the matching function here
    vector<int> vec;
    vec.push_back(3);
    vec.push_back(3);
    std::for_each(vec.begin(), vec.end(), myprint);  // and here
    return 0;
}

関数をオーバーロードしました。機能myprintするはずですが、機能しません。最初myprintmyprint1に、2番目をに変更するmyprint2と機能します。どんな体も助けることができますか?コンパイルエラーは次のとおりです。

funcTemOverload.cpp: In function 'int main()':
funcTemOverload.cpp:29:54: error: no matching function for call to 'for_each(std::map<std::basic_string<char>, int>::iterator, std::map<std::basic_string<char>, int>::iterator, <unresolved overloaded function type>)'
funcTemOverload.cpp:29:54: note: candidate is:
In file included from d:\mingw\bin\../lib/gcc/x86_64-w64-mingw32/4.7.2/include/c++/algorithm:63:0,
         from funcTemOverload.cpp:2:
d:\mingw\bin\../lib/gcc/x86_64-w64-mingw32/4.7.2/include/c++/bits/stl_algo.h:4436:5: note: template<class _IIter, class _Funct> _Funct std::for_each(_IIter, _IIter, _Funct)
d:\mingw\bin\../lib/gcc/x86_64-w64-mingw32/4.7.2/include/c++/bits/stl_algo.h:4436:5: note:   template argument deduction/substitution failed:
funcTemOverload.cpp:29:54: note:   couldn't deduce template parameter '_Funct'
funcTemOverload.cpp:35:50: error: no matching function for call to 'for_each(std::vector<int>::iterator, std::vector<int>::iterator, <unresolved overloaded function type>)'
funcTemOverload.cpp:35:50: note: candidate is:
In file included from d:\mingw\bin\../lib/gcc/x86_64-w64-mingw32/4.7.2/include/c++/algorithm:63:0,
         from funcTemOverload.cpp:2:
d:\mingw\bin\../lib/gcc/x86_64-w64-mingw32/4.7.2/include/c++/bits/stl_algo.h:4436:5: note: template<class _IIter, class _Funct> _Funct std::for_each(_IIter, _IIter, _Funct)
d:\mingw\bin\../lib/gcc/x86_64-w64-mingw32/4.7.2/include/c++/bits/stl_algo.h:4436:5: note:   template argument deduction/substitution failed:
funcTemOverload.cpp:35:50: note:   couldn't deduce template parameter '_Funct'
4

1 に答える 1

6

要求に応じて、元のコードが失敗する理由は、のUnaryFunctionテンプレートパラメータがstd::for_each「非推定コンテキスト」でのみ使用され、明示的に指定されていないためです。[temp.deduct.type]/4

...テンプレートパラメータが推定されないコンテキストでのみ使用され、明示的に指定されていない場合、テンプレート引数の推定は失敗します。

UnaryFunctionのために非推定コンテキストとして扱われます[temp.deduct.call]/6

P [UnaryFunction]が関数型、関数型へのポインタ、またはメンバー関数型へのポインタの場合...引数[myprint]がオーバーロードセット(関数テンプレートを含まない)の場合、それぞれを使用して試行引数の推定が試行されます。セットのメンバー。オーバーロードセットメンバーの1つだけで控除が成功した場合、そのメンバーが控除の引数値として使用されます。オーバーロードセットの複数のメンバーに対して推論が成功した場合、パラメーターは推論されていないコンテキストとして扱われます。

1つのオプションは、キャストを追加することです。

std::for_each(
    g_map.begin(), g_map.end(),
    static_cast<void (*)(std::pair<const string, int>)>(myprint));

std::for_each(
    vec.begin(), vec.end(),
    static_cast<void (*)(int)>(myprint));

もう1つのオプションはmyprint、関数オブジェクトにすることです。これにより、過負荷の解決が内部で発生しますstd::for_each

struct myprint {
    void operator()(std::pair<const string, int> ci) const {
        cout << "first : " << ci.first << "seconde : " << ci.second << endl;
    }
    void operator()(int ci) const {
        cout << ci << endl;
    }
};

std::for_each(g_map.begin(), g_map.end(), myprint());
std::for_each(vec.begin(), vec.end(), myprint());
于 2012-11-23T10:33:41.303 に答える