STL for_each抱怨参数列表

时间:2011-01-20 11:52:31

标签: c++ stl mem-fun

作为家庭作业的一部分,我们应该映射地图中每个角色的出现。我们的函数应该使用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 *

我做错了什么?

4 个答案:

答案 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;
}