gpt4 book ai didi

c++ - 检查范围内的元素是否可以移动?

转载 作者:搜寻专家 更新时间:2023-10-31 02:03:02 25 4
gpt4 key购买 nike

我正在尝试 c++20 的范围接口(interface),并且我添加了一个构造函数,它采用我的类容器类型中的范围。

class element {
...
};

class myclass {
public:
template <typename Iter>
myclass(Iter first, Iter last)
: els(first, last)
{ }

template <typename Range>
myclass(Range&& r);

private:
std::vector<element> els;
};

迭代器对版本非常简单。在 els_(first, last); ,如果 Iter 是普通迭代器,它复制元素,如果 Iter 是可移动迭代器,它移动元素,例如 std::move_iterator<> .如果调用者想要移动元素,则调用者有责任明确提供可移动的迭代器。

然而,在范围版本中,虽然我可以检查范围本身是否在右值引用或左值引用中给出,但它无助于检查元素是否可以移动。

假设我们有一个测距仪,make_range() ,它接受一个容器并返回一个符合范围概念的代理实例。在以下代码中,Range在这两种情况下,构造函数的引用都是右值引用,但显然在第二种情况下不应移动元素。

std::list<element> list_of_elements{...};
myclass c(std::move(list_of_elements)); // should be moved

std::list<element> list_of_elements_to_be_reused{...};
myclass c(make_range(list_of_elements_to_be_reused)); // should not be moved

如何检查给定范围是否用于复制或移动?

最佳答案

你不知道。您信任 std::ranges::begin 返回的迭代器,就像您信任迭代器 Iter 做正确的事情一样。你的第二个构造函数可以委托(delegate):

template <std::ranges::Range Range> // Constraints checked with the library concept
myclass(Range&& r) : myclass(std::ranges::begin(std::move(r)), std::ranges::end(std::move(r)))
{}

默认行为复制,这是明智的。但由于 std::ranges::begin 是自定义点对象,它可以通过 ADL 获取用户定义的 begin 重载。对于用户定义的类型,此设置:

namespace myns {
class myclass { /* ... */ };
auto begin(std::vector<myclass>&& v) { return std::make_move_iterator(v.begin()); }
auto end(std::vector<myclass>&& v) { /* ... * }
}

当向类构造函数传递右值 vector 时,将使 std::ranges::begin 调用 myns::begin。控制行为的是用户定义的类型,这很好。

关于c++ - 检查范围内的元素是否可以移动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56096579/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com