Рассмотрим простой класс A
, который может использоваться как диапазон:
struct A {
~A() { std::cout << "~A "; }
const char* begin() const {
std::cout << "A::begin ";
return s.data();
}
const char* end() const {
std::cout << "A::end ";
return s.data() + s.size();
}
std::string s;
};
Если я делаю временный A
в диапазоне, он работает точно так, как я надеюсь:
for (auto c : A{"works"}) {
std::cout << c << ' ';
}
// output
A::begin A::end w o r k s ~A
Однако, если я попытаюсь обернуть временное:
struct wrap {
wrap(A&& a) : a(std::move(a))
{ }
const char* begin() const { return a.begin(); }
const char* end() const { return a.end(); }
A&& a;
};
for (auto c : wrap(A{"fails"})) {
std::cout << c << ' ';
}
// The temporary A gets destroyed before the loop even begins:
~A A::begin A::end
^^
Почему A
срок жизни не расширен для полного выражения для диапазона, и как я могу это сделать, не прибегая к созданию копии A
?