我有这个奇怪的问题(我在这里简化了代码)和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'工厂,一切正常。
我真的无法理解这是一个铿锵的错误还是我的误解。
答案 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_; }