在 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 进行编译,除非我使用 …
为什么Eigen::VectorXd不满足这个概念std::ranges::contiguous_range?即static_assert(std::ranges::contiguous_range<Eigen::VectorXd>);
不编译。
另外,是否有可能专门化一个模板来使特征向量满足连续范围概念?例如,我们可以专门std::ranges::enable_borrowed_range使任何范围满足该std::range::borrowed_range概念。换句话说,有没有办法让上面的静态断言编译?
#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) 是否有任何标准功能可以创建所有对的范围/视图?以下代码说明了我要创建的视图:
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 循环来迭代此结构很简单。
我试图将我认为是纯右值的内容传递到范围适配器闭包对象中。除非我将名称绑定到初始值设定项列表并使其成为左值,否则它不会编译。这里发生了什么?
#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) 请参阅下面的代码(也可在此处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) 我不明白搬家的要求从何而来。forward_range我在and ...\n基本示例中找不到它sized_sentinel:
\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) 假设我有 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++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) 使用 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)
这里的理由是什么?我如何知道哪些与系列相关的漂亮设施可以合并到管道中?(后者是我凭直觉写的;从概念上讲,这似乎是执行此操作的“新范围方式”。)