gpt4 book ai didi

c++ - begin() 和 end() 不应该只对类的左值引用调用吗?

转载 作者:搜寻专家 更新时间:2023-10-31 01:26:32 26 4
gpt4 key购买 nike

考虑以下代码:

struct iterator{};

struct foo {
iterator begin() &{
return {};
}
iterator end() &{
return {};
}
};

struct bar {
iterator begin(){
return {};
}
iterator end(){
return {};
}
};

void baz(){
//this obviously wouldn't compile
//vvvvvvvvvvvvv
//foo().begin();
bar().begin();
}

这当然是玩具示例,foobar 结构模拟 C++ 集合的工作。我的问题是是否有任何好的论据来保持 beginend 函数可调用右值引用(如 bar)?或者我应该遵循 foo 的想法来使代码更安全吗?据我所知,从临时集合中获取迭代器通常是个坏主意。但另一方面,STL 中的所有集合都适用于左值和右值引用,所以也许我遗漏了什么

live example

最佳答案

我假设您正在考虑这样一种情况,其中 begin 在生命周期结束的纯右值上被调用,因此它导致 foo().begin() 成为悬挂指针,因为临时 foo() 已被破坏。

但情况并非总是如此。仅仅因为一个值是纯右值或亡值并不意味着从对 foo::begin()iterator::operator* 的调用中 foo 对象将被销毁或清空。考虑一下:

#include <utility>

template<class T> void do_something_with(const T&);

template<class T>
void baz(T&& it) {
auto begin = std::forward<T>(it).begin();
auto end = std::forward<T>(it).end();
for (; begin != end; ++begin) {
do_something_with(*begin);
}
}

void bar() {
baz(foo());
// Calls `baz<foo>(foo())`, with `decltype(it)` being `foo&&`
}

但这是一个完全有效的用例。不要将值类型(右值或左值)与生命周期混淆。

关于c++ - begin() 和 end() 不应该只对类的左值引用调用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55191106/

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