Проблема при передаче std :: function в качестве параметра

У меня странная проблема (здесь я упростил код) с clang 3.1 (gcc работает нормально).
Это неправильное использование std :: function (передается по значению) или ошибка clang?

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;
}

Я использую Apple clang 4.1 (llvm 3.1) на Max OS X Lion.

Если я изменяю тип второго параметра на что-то другое (например, int), все работает нормально.

Если я создаю объект A непосредственно из ctor, вместо использования фабрики ‘make’, все работает нормально.

Я действительно не могу понять, является ли это лягушатником или моим недоразумением.

2

Решение

Вы передаете 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_; }
6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]