标签: std-ranges

使用 C++20 在编译时检查容器中是否存在重复元素

在 C++20 之前执行此操作的一种简单方法是执行嵌套循环:

template<typename Container>
constexpr bool has_duplicate(Container&& container)
{
    for (auto it1 = container.cbegin(); it1 != container.cend(); ++it1)
        for(auto it2 = container.cbegin(); it2 != it1; ++it2)
            if (*it1 == *it2)
                return 1;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

通过在基于范围的 for 循环中添加 init 语句,并引入ranges::subrange,我相信这个函数可以用基于范围的 for 循环重写:

template<std::ranges::input_range Container>
constexpr bool has_duplicate(Container&& container)
{
    for(auto it = container.cbegin(); const auto& obj1 : container)
        for(const auto& obj2 : std::ranges::subrange(container.cbegin(), it++))
            if(obj1 == obj2) 
                return 1;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

虽然它在 gcc 上运行良好,但无法使用 clang 进行编译,除非我使用 …

c++ c++20 std-ranges

3
推荐指数
1
解决办法
158
查看次数

向量不满足 Eigen 3.4 中的 std::ranges::contigious_range

为什么Eigen::VectorXd不满足这个概念std::ranges::contiguous_range?即static_assert(std::ranges::contiguous_range<Eigen::VectorXd>); 不编译。

另外,是否有可能专门化一个模板来使特征向量满足连续范围概念?例如,我们可以专门std::ranges::enable_borrowed_range使任何范围满足该std::range::borrowed_range概念。换句话说,有没有办法让上面的静态断言编译?

c++ eigen eigen3 c++20 std-ranges

3
推荐指数
1
解决办法
520
查看次数

范围视图大小无法编译

#include <iostream>
#include <cstdlib>
#include <vector>
#include <ranges>
#include <algorithm>
using namespace std;


int main()
{
    vector<int> ints = {1,2,3,4,5};
    auto v = ints | views::take_while([](int i){return i<3;}) ;
    for (int i : v) std::cout << i << ' ';
    std::cout << '\n';
    int size = v.size();
    std::cout << size << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

v.size() 无法编译。你怎么做到这一点 ?

prog.cc: In function 'int main()':
prog.cc:16:23: error: no matching function for call to 'std::ranges::take_while_view<std::ranges::ref_view<std::vector<int> >, main()::<lambda(int)> >::size()'
   16 |     int size = v.size();
      | …
Run Code Online (Sandbox Code Playgroud)

c++ size c++20 std-ranges

3
推荐指数
1
解决办法
546
查看次数

是否有任何标准功能可以使用容器作为mapped_type 创建地图的扁平视图?

是否有任何标准功能可以创建所有对的范围/视图?以下代码说明了我要创建的视图:

std::unordered_map<std::string, std::vector<int>> m{{"Foo", {1,2}}, {"Hello", {4,5}}};
auto view = ???;
std::vector<std::pair<std::string, int>> v{view.begin(), view.end()};
std::vector<std::pair<std::string, int>> out1{{"Foo", 1}, {"Foo", 2}, {"Hello", 4}, {"Hello", 5}};
std::vector<std::pair<std::string, int>> out2{{"Hello", 4}, {"Hello", 5}, {"Foo", 1}, {"Foo", 2}};
assert(v == out1 || v == out2);
Run Code Online (Sandbox Code Playgroud)

注意:编写一个嵌套的 for 循环来迭代此结构很简单。

c++ c++20 std-ranges

3
推荐指数
1
解决办法
688
查看次数

范围和临时初始化列表

我试图将我认为是纯右值的内容传递到范围适配器闭包对象中。除非我将名称绑定到初始值设定项列表并使其成为左值,否则它不会编译。这里发生了什么?

#include <bits/stdc++.h>

using namespace std;

int main(){
  //why does this compile?
  auto init_list = {1,2,4};
  auto v = init_list | views::drop(1);
  
  //but not this?
  // auto v2 = initializer_list<int>{1,2,4} | views::drop(1);

  //or this?
  //auto v3 = views::all(initializer_list<int>{1,2,4}) | views::drop(1);
}
Run Code Online (Sandbox Code Playgroud)

c++ c++20 std-ranges

3
推荐指数
1
解决办法
816
查看次数

如何为 std::pair 引用包装器的范围定义 C++ 概念?

请参阅下面的代码(也可在此处https://www.godbolt.org/z/hvnvEv1ar)。rng如果我取消注释或的约束,代码将无法编译pair。我觉得我错过了一些微不足道的东西,但我无法弄清楚为什么不满足约束。

#include <vector>
#include <ranges>
#include <utility>

template <typename T>
struct is_reference_wrapper : std::false_type {};
template <typename T>
struct is_reference_wrapper<std::reference_wrapper<T>> : std::true_type {};
template <typename T>
inline constexpr bool is_reference_wrapper_v = is_reference_wrapper<T>::value;
template <typename T>
concept ReferenceWrapper = is_reference_wrapper_v<T>;
template <typename T>
concept ReferenceWrapperPair = requires(const T& t) {
    { t.first } -> ReferenceWrapper;
    { t.second } -> ReferenceWrapper;
};
template <typename T>
concept ReferenceWrapperPairRange =
    std::ranges::range<T> && ReferenceWrapperPair<std::ranges::range_value_t<T>>;

int main()
{
    std::vector<std::pair<int, int>> …
Run Code Online (Sandbox Code Playgroud)

c++ c++-concepts c++20 std-ranges

3
推荐指数
1
解决办法
283
查看次数

为什么 range::view_interface&lt;T&gt;::size 需要移动构造函数

我不明白搬家的要求从何而来。forward_range我在and ...\n基本示例中找不到它sized_sentinel

\n
\n    #include <ranges>\n    #include <string>\n    #include <iostream>\n    \n    class vrange: public std::ranges::view_interface<vrange>\n    {\n        public:\n            vrange(std::string &d): data(d){;};\n    \n            vrange(const vrange &&) = delete;\n    \n            auto begin() const noexcept { return data.begin(); };\n            auto end() const noexcept { return data.end(); };\n    \n        private:\n            std::string data;\n    };\n    \n    int main(){\n        std::string h("Hello world");\n        vrange r(h);\n    \n        std::cout << r.size() << std::endl;\n        for (const auto &i: r){\n            std::cout << i;\n            }\n        std::cout << std::endl;\n        \n    \n …
Run Code Online (Sandbox Code Playgroud)

c++ c++-concepts c++20 std-ranges

3
推荐指数
1
解决办法
144
查看次数

是否可以在 cpp20 中制作范围向量

假设我有 aa vector<vector<int>>。我想ranges::transform以这样的方式使用我得到

vector<vector<int>> original_vectors;
using T = decltype(ranges::views::transform(original_vectors[0], [&](int x){
              return x;
          }));
vector<int> transformation_coeff;
vector<T> transformed_vectors;
for(int i=0;i<n;i++){
    transformed_vectors.push_back(ranges::views::transform(original_vectors[i], [&](int x){
        return x * transformation_coeff[i];
    }));
}
Run Code Online (Sandbox Code Playgroud)

目前在 C++ 中是否可以进行这样的转换或类似的转换?

我知道可以简单地存储transformation_coeff,但在每一步都应用它很不方便。(这将重复多次,因此需要在 中完成O(log n),因此我无法显式应用转换)。

c++ c++20 std-ranges

3
推荐指数
1
解决办法
278
查看次数

如何使用成员函数进行标准库范围操作

我需要查找目录中的所有常规文件,并希望使用 C++20 范围(不是 Eric Niebler 的 range-v3)库。我想出了以下代码:

namespace fs = std::filesystem;

std::vector<fs::directory_entry> entries{ fs::directory_iterator("D:\\Path"), fs::directory_iterator() };

std::vector<fs::path> paths;
std::ranges::copy(entries |
    std::views::filter([](const fs::directory_entry& entry) { return entry.is_regular_file(); }) |
    std::views::transform([](const fs::directory_entry& entry) { return entry.path(); }),
    std::back_inserter(paths));
Run Code Online (Sandbox Code Playgroud)

这可行,但我对使用 lambda 的额外样板感到不舒服;我习惯了 Java 8 流库,我不明白为什么不能直接使用成员函数。这是我第一次尝试重构:

std::ranges::copy(entries |
    std::views::filter(fs::directory_entry::is_regular_file) |
    std::views::transform(fs::directory_entry::path),
    std::back_inserter(paths));
Run Code Online (Sandbox Code Playgroud)

这导致了编译器错误:

error C3867: 'std::filesystem::directory_entry::is_regular_file': non-standard syntax; use '&' to create a pointer to member
error C3889: call to object of class type 'std::ranges::views::_Filter_fn': no matching call operator found
...
Run Code Online (Sandbox Code Playgroud)

所以我尝试了这个:

std::ranges::copy(entries | …
Run Code Online (Sandbox Code Playgroud)

c++ c++20 std-ranges

3
推荐指数
1
解决办法
613
查看次数

C++20 及更高版本:哪些视图/算法可以通过管道传输?

使用 g++-std=C++20或更高版本,可以编译以下内容(假设 vec 是适当类型的向量):

auto isEven = [](auto i) { return i % 2 == 0; }
auto filtered = vec | std::views::filter(isEven);
auto minEven = std::ranges::min_element(filtered);
Run Code Online (Sandbox Code Playgroud)

但以下情况则不然( 的​​参数数量错误std::ranges::__min_element_fn):

auto isEven = [](auto i) { return i % 2 == 0; }
auto minEven = vec | std::views::filter(isEven) | std::ranges::min_element();
Run Code Online (Sandbox Code Playgroud)

这里的理由是什么?我如何知道哪些与系列相关的漂亮设施可以合并到管道中?(后者是我凭直觉写的;从概念上讲,这似乎是执行此操作的“新范围方式”。)

c++ std-ranges

3
推荐指数
1
解决办法
337
查看次数

标签 统计

c++ ×10

std-ranges ×10

c++20 ×9

c++-concepts ×2

eigen ×1

eigen3 ×1

size ×1