【问题标题】:Issue when passing std::function as a parameter将 std::function 作为参数传递时的问题
【发布时间】:2012-12-30 11:56:45
【问题描述】:

我在使用 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”工厂,那么一切正常。

我真的不明白是clang bug还是我的误会。

【问题讨论】:

    标签: c++ clang std-function


    【解决方案1】:

    您将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_; }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-20
      • 1970-01-01
      • 2015-11-25
      • 2016-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多