I’m having this strange issue (I’ve simplified the code here) with clang 3.1 (gcc works fine).
Is it improper use of std::function (passed by value) or a 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;
}
I’m using Apple clang 4.1 (llvm 3.1) on Max OS X Lion.
If I change the type of the second parameter to something else (such as int), everything works fine.
If I construct the A object directly from the ctor, instead of using the ‘make’ factory, everything works fine.
I really can’t understand whether it’s a clang bug or my misunderstanding.
You are passing the
stringby value in to the constructor ofA, and then creating an iterator in to the local string. The string is then destroyed at the end of the constructor, leaving you with an invalid iterator and undefined behavior.