2012-11-23 96 views
2

这里是代码:呼叫没有匹配功能的for_each

#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,我认为这应该是工作,但事实并非如此。当我将第一个myprint更改为myprint1,第二个更改为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' 
+0

请学会格式你的代码。粘贴时,选择它并按CTRL + K. –

+0

感谢您的建议,我从来没有使用'CTRL + K',这是一个非常好的捷径。我曾经在emacs中格式化并粘贴在电路板上。 – toolchainX

回答

5

按照要求,你的原代码失败的原因是,std::for_eachUnaryFunction模板参数在“非推导上下文”只使用,并且没有明确规定。 [temp.deduct.type]/4

...如果一个模板参数仅用于未推导的上下文中,并且未明确指定,则模板参数推导失败。

UnaryFunction被视为由于[temp.deduct.call]/6

非推导出上下文当P [UnaryFunction]是一个功能类型,函数指针类型或成员函数指针类型...如果参数[myprint]是一个重载集合(不包含函数模板),尝试使用集合中的每个成员尝试推论。如果只有一个超载集合成员的扣分成功,则该成员将用作扣减的参数值。 如果扣除成功超过一个超载集的成员,则该参数将被视为未推导的上下文。

一种选择是添加石膏:

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)); 

另一种选择是让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()); 
+0

解决方案效果很好!谢谢!我想知道它为什么不起作用?有没有我打破的C++语言的规则? – toolchainX