【问题标题】:Compilation errors calling find_if using a functor使用仿函数调用 find_if 的编译错误
【发布时间】:2010-06-10 08:36:07
【问题描述】:

我们在使用 find_if 搜索对的向量以查找其中第一个元素与特定值匹配的条目时遇到了一些麻烦。为了完成这项工作,我们定义了一个普通函子,它的 operator() 将一对作为输入并将第一个条目与字符串进行比较。

不幸的是,当我们使用使用临时字符串值构造的仿函数实例实际添加对 find_if 的调用时,编译器会产生大量错误消息。奇怪的是(对我来说,无论如何),如果我们用我们在堆栈上创建的字符串替换临时的,事情似乎工作。

以下是代码(包括两个版本)的样子:

typedef std::pair<std::string, std::string> MyPair;
typedef std::vector<MyPair> MyVector;

struct MyFunctor: std::unary_function <const MyPair&, bool>
{
  explicit MyFunctor(const std::string& val)
    : m_val(val) {}

  bool operator() (const MyPair& p)
  {
    return p.first == m_val;
  }

  const std::string m_val;
};

bool f(const char* s)
{
  MyFunctor f(std::string(s));  // ERROR
  // std::string str(s);                                                                                                  
  // MyFunctor f(str);              // OK                                                                                                    
  MyVector vec;
  MyVector::const_iterator i = std::find_if(vec.begin(), vec.end(), f);
  return i != vec.end();
}

这是最有趣的错误消息:

/usr/include/c++/4.2.1/bits/stl_algo.h:260: 错误:从 'std::pair, std::allocator >, std::basic_string, std::allocator >>' 转换到非标量类型 'std::string' 请求

因为我们有一个解决方法,所以我们很想知道为什么第一种形式会导致问题。我确定我们遗漏了一些东西,但我们无法弄清楚它是什么。

【问题讨论】:

  • 函子?这让我笑了:)
  • @VoodooChild,为什么?在这种情况下,函子一词是正确的。

标签: c++ stl


【解决方案1】:

这是most vexing parse

你可以这样做:

MyFunctor f(s);

MyFunctor f((std::string(s)));

原文声明了一个函数ff 接受一个参数,一个指向函数的指针,该函数接受一个参数 s 并返回 std::string

【讨论】:

  • 谢谢!这完美地澄清了情况。
  • ... 或者简单地说:MyFunctor f( s )。存在从const char*std::string 的隐式转换,因此无需强制转换。
【解决方案2】:
MyFunctor f = MyFunctor(s);

更清晰,效果相同。

【讨论】:

  • ... 或MyFunctor f(s),更简单明了(至少对我而言)
【解决方案3】:

第一个错误在

MyFunctor f(std::string(s));

是因为 std::string(s) 是一个右值(临时)和函数

explicit MyFunctor(const std::string& val)

需要一个不能从右值获取的引用。

您收到的第二条错误消息是因为您在 vector&lt;pair&lt;string, string&gt;&gt; 上进行迭代,这需要一个接受 pair&lt;string, string&gt; 类型输入的函子,但您的函子接受 string 类型的输入,这会导致编译错误。

【讨论】:

  • MyFunctor 构造函数采用const 对字符串的引用。由于const,暂时可以。一旦构造了仿函数,find_if 只关心 operator() 采用什么参数。这需要对 MyPair 的 const 引用,因为它应该这样做。
猜你喜欢
  • 2015-05-05
  • 2018-09-15
  • 2018-05-05
  • 1970-01-01
  • 1970-01-01
  • 2021-10-12
  • 1970-01-01
  • 2014-04-01
  • 2021-06-18
相关资源
最近更新 更多