作为家庭作业的一部分,我们应该映射地图中每个角色的出现。我们的函数应该使用std :: for_each并传入要计算的字符。
我的功能是:
std::for_each(document_.begin(),
document_.end(),
std::mem_fun(&CharStatistics::fillMap));
document_
是string
,fillMap函数定义为
void CharStatistics::fillMap(char ch)
{
ch = tolower(ch);
++chars_.find(ch)->second;
}
chars_
被声明为std::map<char, unsigned int> chars_;
。
我认为这应该有用,但编译器正在抱怨
error C2064: term does not evaluate to a function taking 1 arguments
这使我感到困惑,因为当我查看参数列表时
_Fn1=std::mem_fun1_t<void,CharStatistics,char>,
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Alloc=std::allocator<char>,
1> _Result=void,
1> _Ty=CharStatistics,
1> _Arg=char,
1> _InIt=std::_String_iterator<char,std::char_traits<char>,std::allocator<char>>
对我来说很好看。 _Elem是一个char,我的函数接受一个char。迭代器只不过是char *
我做错了什么?
答案 0 :(得分:6)
CharStatistics::fillMap
不是一个带1个参数的函数。它是成员函数,所以它有隐含的第一个参数 - 指向类实例的指针。
代码:
std::for_each(document_.begin(),
document_.end(),
std::mem_fun(&CharStatistics::fillMap));
for_each
不知道您要拨打CharStatistics::fillMap
的实例,但您没有指定它。您需要将它与任何CharStatistics实例绑定,例如:
std::bind1st(std::mem_fun(&CharStatistics::fillMap), &char_statistics_instance)
答案 1 :(得分:2)
document_是一组字符?
但该函数是CharStatistics的成员函数!大概你是从CharStatistics的成员函数调用它。在这种情况下,如果允许,可以使用boost :: bind来解决它:
std::for_each( document_.begin(), document_.end(),
boost::bind( &CharStatistics::fillMap, this, _1 );
你可以在“this”上使用std :: bind1st,因为你还需要mem_fun
std::for_each( document_.begin(), document_.end(),
std::bind1st( std::mem_fun(&CharStatistics::fillMap), this ) );
实际上看起来非常复杂。这就是新绑定更好的原因!
如果你不允许使用boost :: bind并且你不喜欢mem_fun解决方案,那么编写你自己的functor来重载operator()来获取一个char。像这样:
struct CharStatsFunctor
{
typedef std::map< char, size_t > map_type;
map_type & mapToFill;
explicit CharStatsFunctor( map_type & m ) : mapToFill( m ) {}
void operator()(char ch ) const
{
++mapToFill[ ::tolower( ch ) ];
}
};
在循环调用中
std::for_each( document_.begin(), document_.end(), CharStatsFunctor( chars_ ) );
请注意,fillMap函数中存在错误。我给出的解决方案将起作用。
答案 2 :(得分:1)
如果CharStatistics::fillMap
不是静态成员函数,则需要将调用绑定到实例:
CharStatistics instance;
std::for_each(
document_.begin(),
document_.end(),
std::bind1st(
&CharStatistics::fillMap,
&instance
)
);
此外,如果它不是静态成员函数,那么它实际上有两个参数。第一个是隐式this
指针,第二个是char
。因此,您必须使用boost::bind
绑定两个参数(如果您使用的是C ++ 0x,则绑定std::bind
):
CharStatistics instance;
std::for_each(
document_.begin(),
document_.end(),
boost::bind(
&CharStatistics::fillMap,
&instance,
_1
)
);
for_each
现在应该将bind2nd
实例视为一个带有一个参数(_1
)的函数对象,该实例将自动传递。
答案 3 :(得分:1)
基本上错误的是您的容器的值类型为char
,而for_each
需要一个参数为char
的函数,但std::mem_fun(&CharStatistics::fillMap)
求值为函数对象,它接受CharStatistics
的实例(然后它将调用fillMap
)
为什么不简单地改变你的功能:
void CharStatistics::fillMap(std::string const& str)
{
std::string::const_iterator it(str.begin()), end(str.end());
for(; it != end; ++it)
++chars_.find(tolower(*it))->second;
}