如何将修改应用到局部范围并 return 它?
How do I apply modifications to a locally scoped range and return it?
下面的代码,当使用 --std=c++20 -D_GLIBCXX_DEBUG
在 g++-11.3 下编译并执行时,会产生一个关于迭代器的奇怪的运行时错误。我不太确定这是什么意思,但我怀疑它与向量 range
超出范围有关 test()
returns: range
不被移动或复制,而不是管道运算符 returns 只是保留对 range
.
的引用
#include <ranges>
#include <unordered_set>
#include <vector>
auto to_unordered_set(auto && range) {
using r_type = std::ranges::range_value_t<decltype(range)>;
auto common = range | std::views::common;
return std::unordered_set<r_type>(std::ranges::begin(common), std::ranges::end(common));
}
auto test() {
std::vector<int> range {1,2,3,4,5};
return range | std::ranges::views::transform([](auto x) { return x%2; });
}
int main() {
auto y = to_unordered_set(test());
return 0;
}
/*
/opt/compiler-explorer/gcc-11.3.0/include/c++/11.3.0/debug/safe_iterator.h:195:
In function:
__gnu_debug::_Safe_iterator<_Iterator, _Sequence,
_Category>::_Safe_iterator(__gnu_debug::_Safe_iterator<_Iterator,
_Sequence, _Category>&&) [with _Iterator =
__gnu_cxx::__normal_iterator<int*, std::__cxx1998::vector<int,
std::allocator<int> > >; _Sequence = std::__debug::vector<int>;
_Category = std::forward_iterator_tag]
Error: attempt to copy-construct an iterator from a singular iterator.
Objects involved in the operation:
iterator "this" @ 0x0x7ffea2b7a8c0 {
type = __gnu_cxx::__normal_iterator<int*, std::__cxx1998::vector<int, std::allocator<int> > > (mutable iterator);
state = singular;
}
iterator "other" @ 0x0x7ffea2b7a820 {
type = __gnu_cxx::__normal_iterator<int*, std::__cxx1998::vector<int, std::allocator<int> > > (mutable iterator);
state = singular;
references sequence with type 'std::__debug::vector<int, std::allocator<int> >' @ 0x0x7ffea2b7a8b0
}
*/
有没有办法让这样的东西起作用?我基本上想转换/过滤/加入/等..一个范围和return它(整个事物的copy/move得到returned,范围和任何修改都应用到它)。
首先,由于std::vector
本身就是common_range
,transform_view
也会是common_range
,所以这里使用views::common
是多余的。
其次更重要的是,range
是一个局部变量,所以一旦离开test()
就会被销毁,这使得test()
return成为了[=13] =] 持有悬空指针。
Is there anyway to get something like this to work?
感谢P2415,你可以直接return一个transform_view
应用到一个右值vector
,这将构造owning_view
将原始 vector
内容的所有权转移给自己,这将不再导致悬挂。
#include <ranges>
#include <unordered_set>
#include <vector>
auto to_unordered_set(auto && range) {
using r_type = std::ranges::range_value_t<decltype(range)>;
return std::unordered_set<r_type>(
std::ranges::begin(range), std::ranges::end(range));
}
auto test() {
std::vector<int> range {1,2,3,4,5};
return std::move(range) |
std::ranges::views::transform([](auto x) { return x%2; });
}
int main() {
auto y = to_unordered_set(test());
}
下面的代码,当使用 --std=c++20 -D_GLIBCXX_DEBUG
在 g++-11.3 下编译并执行时,会产生一个关于迭代器的奇怪的运行时错误。我不太确定这是什么意思,但我怀疑它与向量 range
超出范围有关 test()
returns: range
不被移动或复制,而不是管道运算符 returns 只是保留对 range
.
#include <ranges>
#include <unordered_set>
#include <vector>
auto to_unordered_set(auto && range) {
using r_type = std::ranges::range_value_t<decltype(range)>;
auto common = range | std::views::common;
return std::unordered_set<r_type>(std::ranges::begin(common), std::ranges::end(common));
}
auto test() {
std::vector<int> range {1,2,3,4,5};
return range | std::ranges::views::transform([](auto x) { return x%2; });
}
int main() {
auto y = to_unordered_set(test());
return 0;
}
/*
/opt/compiler-explorer/gcc-11.3.0/include/c++/11.3.0/debug/safe_iterator.h:195:
In function:
__gnu_debug::_Safe_iterator<_Iterator, _Sequence,
_Category>::_Safe_iterator(__gnu_debug::_Safe_iterator<_Iterator,
_Sequence, _Category>&&) [with _Iterator =
__gnu_cxx::__normal_iterator<int*, std::__cxx1998::vector<int,
std::allocator<int> > >; _Sequence = std::__debug::vector<int>;
_Category = std::forward_iterator_tag]
Error: attempt to copy-construct an iterator from a singular iterator.
Objects involved in the operation:
iterator "this" @ 0x0x7ffea2b7a8c0 {
type = __gnu_cxx::__normal_iterator<int*, std::__cxx1998::vector<int, std::allocator<int> > > (mutable iterator);
state = singular;
}
iterator "other" @ 0x0x7ffea2b7a820 {
type = __gnu_cxx::__normal_iterator<int*, std::__cxx1998::vector<int, std::allocator<int> > > (mutable iterator);
state = singular;
references sequence with type 'std::__debug::vector<int, std::allocator<int> >' @ 0x0x7ffea2b7a8b0
}
*/
有没有办法让这样的东西起作用?我基本上想转换/过滤/加入/等..一个范围和return它(整个事物的copy/move得到returned,范围和任何修改都应用到它)。
首先,由于std::vector
本身就是common_range
,transform_view
也会是common_range
,所以这里使用views::common
是多余的。
其次更重要的是,range
是一个局部变量,所以一旦离开test()
就会被销毁,这使得test()
return成为了[=13] =] 持有悬空指针。
Is there anyway to get something like this to work?
感谢P2415,你可以直接return一个transform_view
应用到一个右值vector
,这将构造owning_view
将原始 vector
内容的所有权转移给自己,这将不再导致悬挂。
#include <ranges>
#include <unordered_set>
#include <vector>
auto to_unordered_set(auto && range) {
using r_type = std::ranges::range_value_t<decltype(range)>;
return std::unordered_set<r_type>(
std::ranges::begin(range), std::ranges::end(range));
}
auto test() {
std::vector<int> range {1,2,3,4,5};
return std::move(range) |
std::ranges::views::transform([](auto x) { return x%2; });
}
int main() {
auto y = to_unordered_set(test());
}