标签: range-v3

为什么范围的算法与std的迭代器不兼容?

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

int main()
{
    auto coll = std::vector{ 1, 2, 3 };

    ranges::copy(
        coll,
        ranges::ostream_iterator<int>{  std::cout, ", " }
    ); // ok

    ranges::copy(
        coll, 
        std::ostream_iterator<int>{ std::cout, ", " }
    ); // error 
}
Run Code Online (Sandbox Code Playgroud)

问题显示在上面的代码中.我使用range-v3-0.3.7.

对我来说,通用算法copy不应该关心目标迭代器类型,只要它满足输出迭代器的要求即可.

如果是这样,为什么范围的算法不与std的迭代器兼容?

c++ iterator c++-concepts range-v3 c++20

11
推荐指数
1
解决办法
528
查看次数

在 range-v3 中,如何从一对迭代器创建一个范围?

给定一对传统的“开始”和“结束”迭代器,如何创建与 range-v3 兼容的范围?

假设我正在编写一个接受两个迭代器的通用函数,以便与遗留代码兼容。

struct result;  

bool keep_line(const std::string&);
result parse_line(const std::string&);

template <typename InputIt>
std::vector<result> parse_lines(InputIt begin, InputIt end)
{
    // This is what I want to do...
    auto lines = ranges::make_range_out_of_legacy_iterators(begin, end);

    return lines 
        | ranges::view::filter(keep_line) 
        | ranges::view::transform(parse_line) 
        | ranges::to<std::vector<result>>();
}
Run Code Online (Sandbox Code Playgroud)

c++ range-v3 c++20

11
推荐指数
1
解决办法
1262
查看次数

我们能用 C++20 构造带有视图的容器吗?

范围将随着 C++20 标准版本进入 C++。

我的问题:我们是否能够构建(现有)任何范围的标准库容器?更重要的是,具有范围视图?

例如,这会不会:

#include <vector>
#include <iostream>
#include <ranges>

int main() {
    auto sq = [](int x) { return x * x; };
    std::vector<int> vec { 3, 4, 5 };
    std::vector<int> squares { std::ranges::views::transform(vec, sq) };
    for(auto i : squares) { std::cout << i << ' '; }
    std::cout << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

是一个打印的有效程序9 16 25

与 range-v3 库一起编译,这是值得的。

c++ range-v3 c++20

11
推荐指数
1
解决办法
432
查看次数

Range-v3 中是否有一种方法可以将元素添加到范围/视图中?

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++ functional-programming range-v3 c++17 std-ranges

11
推荐指数
0
解决办法
637
查看次数

在头文件中声明全局const对象

在Eric Niebler的range-v3库中,他提供了许多标题,每个标题都有自己的全局函数对象.他们都以同样的方式宣布.他提供了一个类模板static_const:

template<typename T>
struct static_const
{
    static constexpr T value {};
};

template<typename T>
constexpr T static_const<T>::value;
Run Code Online (Sandbox Code Playgroud)

然后将类型的每个函数对象F声明为:

namespace
{
    constexpr auto&& f = static_const<F>::value;
}
Run Code Online (Sandbox Code Playgroud)

通过static_const模板未命名的命名空间引入对象有什么好处,而不是只写:

static constexpr F f{};
Run Code Online (Sandbox Code Playgroud)

c++ global-variables c++14 range-v3

10
推荐指数
1
解决办法
373
查看次数

为什么range-v3将其函数对象放入内联命名空间?

在range-v3中,所有函数都是内联命名空间中的全局函数对象:

#if RANGES_CXX_INLINE_VARIABLES < RANGES_CXX_INLINE_VARIABLES_17
#define RANGES_INLINE_VARIABLE(type, name)                              \
    inline namespace function_objects                                   \
    {                                                                   \
        inline namespace                                                \
        {                                                               \
            constexpr auto &name = ::ranges::static_const<type>::value; \
        }                                                               \
    }

#else  // RANGES_CXX_INLINE_VARIABLES >= RANGES_CXX_INLINE_VARIABLES_17
#define RANGES_INLINE_VARIABLE(type, name) \
    inline namespace function_objects      \
    {                                      \
        inline constexpr type name{};      \
    }
#endif // RANGES_CXX_INLINE_VARIABLES
Run Code Online (Sandbox Code Playgroud)

function_objects命名空间的目的是什么?据我所知,它不会在库中的任何其他位置引用.

c++ c++11 inline-namespaces range-v3

10
推荐指数
1
解决办法
360
查看次数

使用Range v3范围,如何将视图和动作组合到单个管道中?

我正在学习C ++ 20范围(使用Range-V3-VS2015)。我有这段代码可以正常工作:

string clean;
auto tmp1 = input | view::remove_if(not_alpha) | view::transform(::tolower);
std::copy(tmp1.begin(), tmp1.end(), std::back_inserter(clean));
auto tmp2 = clean |= action::sort |  action::unique;
Run Code Online (Sandbox Code Playgroud)

不过,我想这两个管道定义结合tmp1tmp2成一个单一的管道。那可能吗?我已经尝试了无数次尝试,包括添加view::move和添加在内view::copy

c++ stl std range-v3

10
推荐指数
1
解决办法
470
查看次数

是否可以/建议返回一个范围?

我正在使用范围库来帮助我的类中的文件管理器数据,如下所示:

class MyClass
{
public:
    MyClass(std::vector<int> v) : vec(v) {}

    std::vector<int> getEvens() const
    {
        auto evens = vec | ranges::views::filter([](int i) { return ! (i % 2); });
        return std::vector<int>(evens.begin(), evens.end());
    }

private:
    std::vector<int> vec;
};
Run Code Online (Sandbox Code Playgroud)

在这种情况下,函数中构造了一个新向量getEvents()。为了节省这种开销,我想知道是否可以/建议直接从函数返回范围?

class MyClass
{
public:
    using RangeReturnType = ???;

    MyClass(std::vector<int> v) : vec(v) {}

    RangeReturnType getEvens() const
    {
        auto evens = vec | ranges::views::filter([](int i) { return ! (i % 2); });
        // ...
        return evens;
    }

private:
    std::vector<int> vec;
};
Run Code Online (Sandbox Code Playgroud)

如果可能的话,我是否需要考虑任何终生注意事项? …

c++ range-v3 c++20

10
推荐指数
2
解决办法
3222
查看次数

如何在 c++20 约束算法中投影 std::tuple

假设我们有一个 s 数组std::pair

using Particle = std::pair<std::string, double>;
Particle particles[] {{"Electron", 0.511}, {"Muon", 105.66}, {"Tau", 1776.86}};
Run Code Online (Sandbox Code Playgroud)

我们可以使用具有不同投影函数的C++20范围算法来根据不同的数据成员对它们进行排序:

ranges::sort(particles, {}, &Particle::first);
ranges::sort(particles, {}, &Particle::second);
Run Code Online (Sandbox Code Playgroud)

这看起来非常干净。但是当我将Particle的数据类型移至std::tuple

using Particle = std::tuple<std::string, double>;
Run Code Online (Sandbox Code Playgroud)

我不能再使用相同的投影度量,因为std::tuple没有firstsecond没有成员。或者,只需传递 lambda 即可正常工作:

ranges::sort(particles, {}, [](const auto& t) { return std::get<0>(t); });
ranges::sort(particles, {}, [](const auto& t) { return std::get<1>(t); });
 
Run Code Online (Sandbox Code Playgroud)

但是有没有更简洁的项目方法可以做到这一点?

ranges::sort(particles, {}, &std::get<0>); 
Run Code Online (Sandbox Code Playgroud)

c++ range-v3 c++20

9
推荐指数
1
解决办法
671
查看次数

如何声明一个需要范围的函数

我想声明一个函数,它获取一个范围作为输入,输出一个数字并将其直接与 range-v3 库的 range::views::transform 一起使用。

以下内容有效,但我必须使用一个实际上不做任何事情的 lambda。

int64_t getGroupValue( ranges::input_range auto&& group ) {
    return ranges::accumulate( group, 1ll, ranges::multiplies() );
}

int64_t calculateGroupSum( const std::vector<int>& data ) {
    using ranges::views::transform;
    using ranges::views::chunk;

    return ranges::accumulate(
        data
        | chunk( 3 )
        | transform( [] ( auto group ) { return getGroupValue( group ); })
        , 0ll);
}
Run Code Online (Sandbox Code Playgroud)

我想做以下事情:

int64_t calculateGroupSum( const std::vector<int>& data ) {
    using ranges::views::transform;
    using ranges::views::chunk;

    return ranges::accumulate(
        data
        | chunk( 3 )
        | transform( getGroupValue )
        , 0ll); …
Run Code Online (Sandbox Code Playgroud)

c++ range-v3

9
推荐指数
1
解决办法
977
查看次数