标签: range-v3

为什么 range-v3 Yield 需要默认构造函数

我试图理解,yield 系列函数要求该类默认可构造的原因是什么?

在以下示例中,仅当 CNum 具有默认构造函数时,vnums1 行才会编译。vnums2 行不需要默认构造函数。

我正在使用 Visual Studio 2017 和 Range-V3-VS2015。谢谢你!

#include <range/v3/all.hpp>

struct CNum
{
    // CNum() = default;
    explicit CNum(int num) : m_num(num) {}
    int m_num;
};

int main()
{
    auto ints = ranges::view::ints(0, 10);

    // this compiles only of CNum has a default constructor
    auto vnums1 = ints
        | ranges::view::for_each([](int num) { return ranges::yield_if(num % 2, CNum(num)); })
        | ranges::to_vector;

    // this compiles even if CNum does not have a default constructor
    auto vnums2 = …
Run Code Online (Sandbox Code Playgroud)

c++ range-v3

6
推荐指数
1
解决办法
509
查看次数

如何使用 range-v3 压缩向量的向量

(这是带有 range-v3 的 Sum 向量的后续)

如果我有两个(或更多)向量,我可以将zip它们组合在一起,range-v3如下所示:

std::vector< int > v1{1,1,1};
std::vector< int > v2{2,2,2};

auto v = ranges::views::zip( v1, v2 )
  | ranges::views::transform( ... );
Run Code Online (Sandbox Code Playgroud)

这很有效,但实际上,我没有显式向量,但我确实有向量的向量。我想做以下事情,但它没有给出相同的结果。(其实我不确定结果是什么,也不知道如何确定结果是什么!)


std::vector< std::vector< int > > V{{1,1,1},{2,2,2}};

auto vV = ranges::views::zip( V )
  | ranges::views::transform( ... );
Run Code Online (Sandbox Code Playgroud)

我该怎么做才能vector< vector >像压缩一些显式向量一样压缩 a ?我尝试过joinstridechunk等一起使用,但还没有找到神奇的组合。

c++ vector range-v3

6
推荐指数
1
解决办法
1098
查看次数

为什么“累积”没有进入 C++20 的范围?

我怀疑这accumulate不是唯一没有成功的算法。

也许现在有更好的方法来在一个范围内执行累积(折叠),因此accumulate已经过时了?

c++ range-v3 c++20

6
推荐指数
1
解决办法
198
查看次数

为什么 range::basic_istream_view::begin() 不被缓存?

我发现c++20与range-v3ranges::basic_istream_view版本略有不同。

最重要的区别是std::ranges::basic_istream_view不会缓存其begin(),因此每个begin()s 将返回具有已读取值的下一个迭代器(godbolt):

auto words = std::istringstream{"today is yesterday's tomorrow"};
auto view = std::ranges::istream_view<std::string>(words);
std::cout << *view.begin() << "\n"; // today
std::cout << *view.begin() << "\n"; // is
std::cout << *view.begin() << "\n"; // yesterday's
std::cout << *view.begin() << "\n"; // tomorrow
Run Code Online (Sandbox Code Playgroud)

考虑以下内容(godbolt),如果我使用 range-v3 版本,则所有三个std::ranges::find()s 都会找到"is",但如果我使用 std 版本,"is"则只会在第一次调用中找到。

auto words = std::istringstream{"today is yesterday's tomorrow"};
auto view = std::ranges::istream_view<std::string>(words);
std::cout << …
Run Code Online (Sandbox Code Playgroud)

c++ range-v3 c++20 std-ranges

6
推荐指数
2
解决办法
237
查看次数

在 C++ 中使用范围是否可取?

我发现大多数 C++ stl 算法的传统语法很烦人;使用它们编写起来很长只是一个小问题,但它们总是需要对现有对象进行操作,这在很大程度上限制了它们的可组合性。

我很高兴看到 stl 中范围的出现;然而,从 C++20 开始,存在严重的缺点:标准库的不同实现对此的支持各不相同,并且 range-v3 中存在的许多内容并未进入 C++20,例如(对我来说)非常令人惊讶),将视图转换为向量(对我来说,如果我无法将计算结果存储在向量中,这会使这一切变得毫无用处)。

另一方面,使用 range-v3 对我来说似乎也不理想:它的文档很少(而且我不同意其中的所有内容都是不言自明的),而且更严重的是,C++20 的想法range 与 range-v3 所做的不同,所以我不能只是说,好吧,让我们坚持使用 range-v3;无论如何,这将在某个时候成为标准。

那么,我应该使用两者中的任何一个吗?或者这一切都不值得,并且通过依赖 std 范围或 range-v3,使我的代码太难以维护和移植?

c++ range-v3 c++20 std-ranges

6
推荐指数
1
解决办法
3901
查看次数

为什么我不能在范围-v3中获得范围的大小?

我想得到名字以'T'开头的人数:

#include <iostream>
#include <string>
#include <range\v3\all.hpp>

using namespace ranges;

int main()
{
    const auto names = std::vector<std::string> {"Tony", "Peter"};

    std::cout << size(names | view::filter([](const auto& s) {return s[0] == 'T';}));
}
Run Code Online (Sandbox Code Playgroud)

但我得到了巨大的编译错误:

? clang -std=c++14 test.cpp
test.cpp:11:18: error: no matching function for call to object of type 'const ranges::v3::adl_size_detail::size_fn'
std::cout << size(names | view::filter([](const auto& s) {return s[0] == 'T';}));
             ^~~~
K:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\range/v3/size.hpp:90:32: note: candidate template
  ignored: substitution failure [with Rng =
  ranges::v3::remove_if_view<ranges::v3::iterator_range<std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<std::basic_string<char,
  std::char_traits<char>, std::allocator<char> …
Run Code Online (Sandbox Code Playgroud)

c++ clang c++11 c++14 range-v3

5
推荐指数
2
解决办法
1024
查看次数

范围-v3中的CONCEPT_REQUIRES_实现

试图学习如何使用Eric Niebler的range-v3库,并阅读源代码,我看到了宏定义:

#define CONCEPT_PP_CAT_(X, Y) X ## Y
#define CONCEPT_PP_CAT(X, Y)  CONCEPT_PP_CAT_(X, Y)

/// \addtogroup group-concepts                                                                                                                                                                  
/// @{                                                                                                                                                                                          
#define CONCEPT_REQUIRES_(...)                                                      \
    int CONCEPT_PP_CAT(_concept_requires_, __LINE__) = 42,                          \
    typename std::enable_if<                                                        \
        (CONCEPT_PP_CAT(_concept_requires_, __LINE__) == 43) || (__VA_ARGS__),      \
        int                                                                         \
    >::type = 0                                                                     \
    /**/
Run Code Online (Sandbox Code Playgroud)

简而言之,模板定义如下:

template<typename I, typename O,
    CONCEPT_REQUIRES_(InputIterator<I>() &&
                      WeaklyIncrementable<O>())>
void fun_signature() {}
Run Code Online (Sandbox Code Playgroud)

翻译为:

template<typename I, typename O,
         int a_unique_name = 42,
         typename std::enable_if
           <false || (InputIterator<I>() &&
                      WeaklyIncrementable<O>()), int>::type = 0
        >
void fun_signature() {}
Run Code Online (Sandbox Code Playgroud)

我想知道为什么宏实现这种方式.为什么需要这个整数,为什么它需要一个false …

c++ template-meta-programming range-v3

5
推荐指数
1
解决办法
172
查看次数

在并行算法中使用range :: view :: iota

由于在没有基于索引的算法并行,我想知道是否可以结合使用来模拟。那是:ranges::view::iotastd::for_each

using namespace std;

constexpr int N= 10'000'000;
ranges::iota_view indices(0,N);
vector<int> v(N);

for_each(execution::par_unseq,indices.begin(),indices.end(),[&](int i) { v[i]= i; });
Run Code Online (Sandbox Code Playgroud)

iota_view似乎提供了对适当类型的随机访问([range.iota.iterator]):

iota_view<I, Bound>::iterator::iterator_category 定义如下:

(1.1) -如果I模型Advanceable,然后iterator_categoryrandom_access_iterator_tag

(1.2) -否则,如果I模型Decrementable,然后iterator_categorybidirectional_iterator_tag

(1.3) -否则,如果I模型Incrementable,然后iterator_categoryforward_iterator_tag

(1.4)-否则iterator_categoryinput_iterator_tag

上面的代码正确吗?使用iota_view这种方式是否会降低性能?


编辑:我已经使用range-v3cmcstl2和Intel的PSTL进行了一些测试。

使用range-v3,以上示例无法使用GCC …

c++ stl-algorithm range-v3 c++17 c++20

5
推荐指数
1
解决办法
1964
查看次数

为什么`range :: view :: for_each`要求函子必须返回`InputRange`概念的模型?

#include <vector>
#include <algorithm>
#include <range/v3/all.hpp>

using namespace ranges;

int main()
{
    auto coll = std::vector{ 1, 2, 3 };
    std::for_each(coll.begin(), coll.end(), [](auto){}); // ok
    coll | view::for_each([](auto){}); // static_assert failure
}
Run Code Online (Sandbox Code Playgroud)

static_assert错误消息:

要使用view :: for_each,函数F必须返回InputRange概念的模型.

std::for_each需要一个返回的仿函数void,为什么ranges::view::for_each要求仿函数必须返回一个InputRange概念模型?

c++ standards concept range-v3 c++20

5
推荐指数
1
解决办法
120
查看次数

如何使用range-v3库从std :: vector获取列视图和行视图?

将7x5矩阵展平为std :: vector,我想使用Eric Niebler的range-v3库获取列和行的视图.到目前为止,我管理(改进的空间)以获得单行,单列和连接行的视图.

请参阅:https://wandbox.org/permlink/8o4RgSucF3zSNuPN

std::vector<int> numbers = {
    00, 01, 02, 03, 04,
    10, 11, 12, 13, 14,
    20, 21, 22, 23, 24,
    30, 31, 32, 33, 34,
    40, 41, 42, 43, 44,
    50, 51, 52, 53, 54,
    60, 61, 62, 63, 64,
};
const size_t n = 5;//number of columns

//Row_3 = {30, 31, 32, 33, 34}
auto Row_3 = numbers | GetRow(3, n);
std::cout << Row_3 << std::endl;

//Col_2 = {02, 12, 22, 32, …
Run Code Online (Sandbox Code Playgroud)

c++ range-v3

5
推荐指数
1
解决办法
142
查看次数