为什么临时容器对象不能在 range-v3 中进行管道传输?
Why aren't temporary container objects pipeable in range-v3?
为什么是下面的
#include <iostream>
#include <string>
#include <range/v3/all.hpp>
std::vector<int> some_ints() {
return { 1,2,3,4,5 };
}
int main() {
auto num_strings = some_ints() |
ranges::views::transform([](int n) {return std::to_string(n); }) |
ranges::to_vector;
for (auto str : num_strings) {
std::cout << str << "\n";
}
return 0;
}
一个错误,而
int main() {
auto ints = some_ints();
auto num_strings = ints |
ranges::views::transform([](int n) {return std::to_string(n); }) |
ranges::to_vector;
for (auto str : num_strings) {
std::cout << str << "\n";
}
return 0;
}
可以吗?
我希望临时的生命周期延长到整个管道表达式的生命周期,所以我不明白问题出在哪里。
Clang 的错误是
<source>:10:36: error: overload resolution selected deleted operator '|'
auto num_strings = some_ints() |
~~~~~~~~~~~ ^
/opt/compiler-explorer/libs/rangesv3/0.11.0/include/range/v3/view/view.hpp:153:13: note: candidate function [with Rng = std::vector<int, std::allocator<int>>, ViewFn = ranges::detail::bind_back_fn_<ranges::views::transform_base_fn, (lambda at <source>:11:34)>] has been explicitly deleted
operator|(Rng &&, view_closure<ViewFn> const &) // ****** READ THIS *******
从Visual Studio我得到
error C2280: 'std::vector<int,std::allocator<int>> ranges::views::view_closure_base_ns::operator |<std::vector<int,std::allocator<int>>,ranges::detail::bind_back_fn_<ranges::views::transform_base_fn,main::<lambda_1>>>(Rng &&,const ranges::views::view_closure<ranges::detail::bind_back_fn_<ranges::views::transform_base_fn,main::<lambda_1>>> &)': attempting to reference a deleted function
1> with
1> [
1> Rng=std::vector<int,std::allocator<int>>
1> ]
这两个错误似乎都在说管道操作符被显式删除以用于 r 值引用?
简短的回答是因为他们很懒,|
不转让所有权。
I would expect the lifetime of the temporary to be extended to the lifetime of the whole pipeline expression so I don't understand what the problem is.
是的,这正是会发生的事情,但仅此而已。这意味着一旦代码命中 ;
,some_ints()
就会死亡,并且 num_strings
现在包含“悬空”范围。所以选择禁止编译这个例子。
为什么是下面的
#include <iostream>
#include <string>
#include <range/v3/all.hpp>
std::vector<int> some_ints() {
return { 1,2,3,4,5 };
}
int main() {
auto num_strings = some_ints() |
ranges::views::transform([](int n) {return std::to_string(n); }) |
ranges::to_vector;
for (auto str : num_strings) {
std::cout << str << "\n";
}
return 0;
}
一个错误,而
int main() {
auto ints = some_ints();
auto num_strings = ints |
ranges::views::transform([](int n) {return std::to_string(n); }) |
ranges::to_vector;
for (auto str : num_strings) {
std::cout << str << "\n";
}
return 0;
}
可以吗?
我希望临时的生命周期延长到整个管道表达式的生命周期,所以我不明白问题出在哪里。
Clang 的错误是
<source>:10:36: error: overload resolution selected deleted operator '|'
auto num_strings = some_ints() |
~~~~~~~~~~~ ^
/opt/compiler-explorer/libs/rangesv3/0.11.0/include/range/v3/view/view.hpp:153:13: note: candidate function [with Rng = std::vector<int, std::allocator<int>>, ViewFn = ranges::detail::bind_back_fn_<ranges::views::transform_base_fn, (lambda at <source>:11:34)>] has been explicitly deleted
operator|(Rng &&, view_closure<ViewFn> const &) // ****** READ THIS *******
从Visual Studio我得到
error C2280: 'std::vector<int,std::allocator<int>> ranges::views::view_closure_base_ns::operator |<std::vector<int,std::allocator<int>>,ranges::detail::bind_back_fn_<ranges::views::transform_base_fn,main::<lambda_1>>>(Rng &&,const ranges::views::view_closure<ranges::detail::bind_back_fn_<ranges::views::transform_base_fn,main::<lambda_1>>> &)': attempting to reference a deleted function
1> with
1> [
1> Rng=std::vector<int,std::allocator<int>>
1> ]
这两个错误似乎都在说管道操作符被显式删除以用于 r 值引用?
简短的回答是因为他们很懒,|
不转让所有权。
I would expect the lifetime of the temporary to be extended to the lifetime of the whole pipeline expression so I don't understand what the problem is.
是的,这正是会发生的事情,但仅此而已。这意味着一旦代码命中 ;
,some_ints()
就会死亡,并且 num_strings
现在包含“悬空”范围。所以选择禁止编译这个例子。