将std :: function作为参数传递时出现问题

时间:2012-12-30 11:56:46

标签: c++ clang std-function

我有这个奇怪的问题(我在这里简化了代码)和clang 3.1(gcc工作得很好)。 是不正当使用std :: function(通过值传递)还是clang bug?

template <typename Container>
struct A
{
  using function_type = std::function<char(char)>;

  A(Container c, function_type f) : it_(c.begin()), f_(f) {}
  typename Container::value_type operator*() { return *it_; }

  typename Container::iterator it_;
  function_type f_;
};

template <typename Cont>
A<Cont> makeA(Cont c, std::function<char(char)> f)
{
  return A<Cont>(c, f);
}

char f(char ch) { return ch; }

int main()
{
  std::string s { "foo" };
  auto a = makeA(s, f); // wraps s.begin()
  std::clog << "main: " << *(s.begin()) << std::endl; // prints 'f'
  std::clog << "main: " << *a << std::endl; // prints garbage
  return 0;
}

我在Max OS X Lion上使用Apple clang 4.1(llvm 3.1)。

如果我将第二个参数的类型更改为其他参数(例如int),一切正常。

如果我直接从ctor构建A对象,而不是使用'make'工厂,一切正常。

我真的无法理解这是一个铿锵的错误还是我的误解。

1 个答案:

答案 0 :(得分:6)

您将值string传递给A的构造函数,然后在本地字符串中创建迭代器。然后在构造函数的末尾销毁该字符串,留下无效的迭代器和未定义的行为。

//`c` is a local copy of the string
A(Container c, function_type f) :
    //c.begin() returns an iterator into `c`
    it_(c.begin()),
    f_(f)
{
}//`c` is destroyed, leaving it_ as a dangling iterator

//Dereferences `it_` -- undefined behaviour
typename Container::value_type operator*() { return *it_; }
相关问题