STL for_each 抱怨参数列表

发布于 2024-10-13 03:49:49 字数 1185 浏览 7 评论 0原文

作为家庭作业的一部分,我们应该绘制地图中每个字符的出现情况。我们的函数应该使用 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字符_;

我认为这应该可行,但是编译器正在抱怨

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 *

我做错了什么?

As part of a homework assignment, we are supposed to map the occurrence of each character in a map. Our function is supposed to use std::for_each and pass in the character to be evaluated.

My function is:

std::for_each(document_.begin(), 
              document_.end(), 
              std::mem_fun(&CharStatistics::fillMap));

document_ is a string, and the fillMap function is defined like

void CharStatistics::fillMap(char ch)
{
    ch = tolower(ch);
    ++chars_.find(ch)->second;
}

chars_ is declared as std::map<char, unsigned int> chars_;.

I figure this should work, but the compiler is complaining

error C2064: term does not evaluate to a function taking 1 arguments

Which confuses me, because when I look at the argument list

_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>>

it looks fine to me. _Elem is a char and my function accepts a char. The iterator is nothing else than a char *

What am I doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

无人问我粥可暖 2024-10-20 03:49:49

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)

CharStatistics::fillMap is not a function taking 1 argument. it's member function and so it has implicit first argument - pointer to class instance.

in code:

std::for_each(document_.begin(), 
              document_.end(), 
              std::mem_fun(&CharStatistics::fillMap));

for_each don't know on which instance you'd like to call CharStatistics::fillMap, you didn't specify it. you need to bind it with any CharStatistics instance, e.g.:

std::bind1st(std::mem_fun(&CharStatistics::fillMap), &char_statistics_instance)
我喜欢麦丽素 2024-10-20 03:49:49

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 解决方案,请编写自己的函子来重载operator()以获取字符。像这样:

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 函数中有一个错误。我给出的解决方案将会起作用。

document_ is a collection of characters?

But the function is a member function of CharStatistics! Presumably you are calling this from a member function of CharStatistics. In that case you can use boost::bind to solve it if that is allowed:

std::for_each( document_.begin(), document_.end(), 
     boost::bind( &CharStatistics::fillMap, this, _1 );

You could use std::bind1st on "this" which is more complex as you still need mem_fun

std::for_each( document_.begin(), document_.end(), 
      std::bind1st( std::mem_fun(&CharStatistics::fillMap), this ) );

which actually is horribly complex looking. That is why the new bind is so much better!

If you are not allowed to use boost::bind and you don't like the mem_fun solution, write your own functor that overloads operator() to take a char. Like this:

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

In the loop call

std::for_each( document_.begin(), document_.end(), CharStatsFunctor( chars_ ) );

Note there is an error in your fillMap function. The solution I gave will work.

暗藏城府 2024-10-20 03:49:49

基本上,错误在于您的容器具有值类型 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;
}

Basically what is wrong is that your container has a value type char, and for_each expects a function which takes an argument of char, but std::mem_fun(&CharStatistics::fillMap) evaluates to a function object which takes an instance of CharStatistics (on which it will then call fillMap)

Why not simply change your function:

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;
}
却一份温柔 2024-10-20 03:49:49

如果 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) 的函数对象,并且该实例将自动传递。

If CharStatistics::fillMap is not a static member function, then you need to bind the call to an instance:

CharStatistics instance;
std::for_each(
     document_.begin(),
     document_.end(),
     std::bind1st(
         &CharStatistics::fillMap,
         &instance
     )
);

Further, if it's not a static member function, then it actually has two arguments. The first is the implicit this pointer, and the second is the char. So you have to bind two arguments, using boost::bind (or std::bind if you are on C++0x):

CharStatistics instance;
std::for_each(
     document_.begin(),
     document_.end(),
     boost::bind(
         &CharStatistics::fillMap,
         &instance,
         _1
     )
);

for_each should now see the bind2nd instance as a function object taking one argument (_1), and the instance will be passed automatically.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文