std::begin和 new 和有什么不一样std::ranges::begin?(同样为end,size等等)
两者似乎工作相同:
#include <iostream>
#include <vector>
#include <array>
#include <ranges>
template<std::ranges::range R>
void printInfo(const R &range)
{
std::cout << (std::ranges::begin(range) == std::begin(range));
}
template<class T>
struct X
{
std::vector<T> v;
auto begin() const { return v.begin(); }
auto end() const { return v.end(); }
};
int main()
{
printInfo(std::vector{1, 2, 3, 4});
printInfo(std::array{1, 2, 3, 4});
printInfo(X<int>{{1, 2, 3, 4}});
int oldSchool[]{1, 2, 3, 4};
printInfo(oldSchool);
}
Run Code Online (Sandbox Code Playgroud)
1111按预期编译和打印。
难道ranges::begin …
为什么这段代码可以在#if 0块就位的情况下工作,但如果删除它,则会失败并显示一组相当复杂的错误消息?更重要的是,我如何使它与上面非常相似的块得到相同的结果?
#include <ranges>
#include <iterator>
#include <optional>
#include <string_view>
#include <iostream>
#include <algorithm>
template <::std::ranges::view View,
typename Pred>
requires ::std::ranges::input_range<View> &&
::std::ranges::common_range<View> &&
::std::is_object_v<Pred> &&
::std::indirect_unary_predicate<const Pred, ::std::ranges::iterator_t<View>>
class skip_after_view : public ::std::ranges::view_interface<skip_after_view<View, Pred>>
{
public:
skip_after_view() = default;
skip_after_view(View v, Pred p)
: subview_(::std::move(v)), pred_(::std::move(p))
{}
class iterator;
friend class iterator;
auto begin() const {
return iterator{subview_.begin(), subview_.end(), &pred_};
}
auto end() const {
return iterator{subview_.end(), subview_.end(), &pred_};
}
private:
View subview_ = View();
Pred pred_; …Run Code Online (Sandbox Code Playgroud) Range-v3 具有ranges::views::drop和 来ranges::views::drop_last从视图的前面或后面删除元素。
它是否提供类似的功能来将元素添加到视图中?
目前,我发现的最短方法是使用 a或 a到concat范围/容器:iotasingle
#include <assert.h>
#include <range/v3/view/iota.hpp>
#include <range/v3/view/concat.hpp>
#include <range/v3/to_container.hpp>
using namespace ranges;
using namespace views;
int main() {
std::vector<int> v{1,2,3};
auto wi = concat(iota(0,1),v);
assert(((wi | to_vector) == std::vector<int>{0,1,2,3}));
auto ws = concat(single(0), v);
assert(((ws | to_vector) == std::vector<int>{0,1,2,3}));
}
Run Code Online (Sandbox Code Playgroud) 我有一段使用 C++20 范围库的代码,取自此 SO anwer。该代码被某些编译器(版本)拒绝,并且某些较旧的 GCC 版本返回垃圾。哪个编译器是正确的?
该代码应该打印 a 中第一列的元素std::vector<std::vector>。
#include <vector>
#include <string>
#include <ranges>
#include <iostream>
int main()
{
// returns a range containing only the i-th element of an iterable container
auto ith_element = [](size_t i) {
// drop the first i elements in the range and take the first element from the remaining range
return std::views::drop(i) | std::views::take(1);
};
// returns a range over the i-th column
auto column = [ith_element](size_t i) …Run Code Online (Sandbox Code Playgroud) 我注意到 C++23zip_view有以下限制:
template<input_range... Views>
requires (view<Views> && ...) && (sizeof...(Views) > 0)
class zip_view;
Run Code Online (Sandbox Code Playgroud)
这意味着只能zip_view压缩输入范围。
我想知道为什么它排除output_range,因为output_range在我看来支持可能很有用。例如,我可以压缩一堆output_ranges 来同时写入,如下场景:
/* zipped input_range */
auto zip_in = views::zip(views::iota(0, 3),
views::iota(3, 6),
views::iota(6, 9));
std::vector<int> v1, v2, v3;
auto make_insert_range = [](auto inserter) {
return ranges::subrange(inserter, std::unreachable_sentinel);
};
/* zipped output_range */
auto zip_out = views::zip(make_insert_range(std::back_inserter(v1)),
make_insert_range(std::back_inserter(v2)),
make_insert_range(std::back_inserter(v3)));
/* copy */
ranges::copy(zip_in, zip_out.begin());
std::println("v1: {}", v1); // v1: [0, 1, 2]
std::println("v2: {}", …Run Code Online (Sandbox Code Playgroud) 我注意到std::ranges::sort无法排序std::vector<bool>:
<source>:6:51: error: no match for call to '(const std::ranges::__sort_fn) (std::vector<bool, std::allocator<bool> >)'
6 | std::ranges::sort(std::vector{false, true, true});
|
Run Code Online (Sandbox Code Playgroud)
这是允许的吗?我们是否需要专门化std::ranges::sortfor std::vector<bool>?是否有关于委员会如何考虑这一点的任何信息?
我想通过转换另一个向量来初始化一个向量。我用两种内联初始化和转换的方式进行了测试std::vector。
一种使用 lambda 内联初始化(使用std::transform):
std::vector<int> foo(100,42);
const auto fooTimesTwo = [&]{
std::vector<int> tmp(foo.size());
std::transform(foo.begin(), foo.end(), tmp.begin(), convert);
return tmp;
}();
Run Code Online (Sandbox Code Playgroud)
而另一个 - 使用std::ranges::views::transform:
std::vector<int> foo(100,42);
auto transform_range = (foo | std::ranges::views::transform(convert));
std::vector<int> fooTimesTwo {
transform_range.begin(),
transform_range.end()
};
Run Code Online (Sandbox Code Playgroud)
我希望两种向量初始化方式都应该具有相似的性能,但由于某种原因,传统解决方案的基准测试std::transform比第二个方法快得多(快 9.7 倍 -> https://quick-bench.com/q/3PSDRO9UbMNunUpdWGNShF49WlQ) .
我的问题是:
std::ranges::views::transform不当吗?旁注 - 可以使用 来完成boost::make_transform_iterator,但我无法在 quick-bench 上检查它,因为它们不支持 boost。所以我不确定这种解决方案的效率。
我正在测试 C++ 20 的范围,这是我的main.cpp:
#include <ranges>
#include <iostream>
int main()
{
auto const ints = {0,1,2,3,4,5};
auto even = [](int i) { return 0 == i % 2; };
auto square = [](int i) { return i * i; };
for (int i : ints | std::views::filter(even) | std::views::transform(square)) {
std::cout << i << ' ';
}
std::cout << '\n';
}
Run Code Online (Sandbox Code Playgroud)
编译它clang++-12但找不到“范围”:
$ clang++-12 --version
Ubuntu clang version 12.0.1-++20210525082622+328a6ec95532-1~exp1~20210525063352.95
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin …Run Code Online (Sandbox Code Playgroud) 这个问题的主要目的是提请社区注意 libstdc++ 范围不适用于 clang:https ://bugs.llvm.org/show_bug.cgi ? id = 46746
Avi Kivity 建议这是一个 gcc 错误:https ://gcc.gnu.org/bugzilla/show_bug.cgi?id=97120
但随后他也暗示这是一个叮当声错误:https ://bugs.llvm.org/show_bug.cgi ? id = 47509
Rafael Ávila de Espíndola 将问题归结为以下代码,该代码使用 gcc 编译,但不使用 clang:
template <typename _Tp>
concept __member_begin = requires(_Tp __t) {
{__t.begin()};
};
template <typename _Tp>
concept nothing = requires(_Tp __t) {
{42};
};
template <typename _Tp>
requires __member_begin<_Tp> void __ranges_begin() {}
template <typename _Derived>
struct view_interface {
void foo() requires __member_begin<_Derived> {}
void bar() requires nothing<decltype(__ranges_begin<_Derived>())> {}
};
struct …Run Code Online (Sandbox Code Playgroud)