gpt4 book ai didi

c++ - C++11标准中是否规定std::begin(Container&&)返回const_iterator?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:09:26 26 4
gpt4 key购买 nike

这里是相关代码的链接:

#include <iostream>
#include <string>
#include <vector>
#include <type_traits>

int main()
{
std::vector<int> v{1, 2, 3, 4, 5};
auto iter = begin(std::move(v));
if(std::is_const<typename std::remove_reference<decltype(*iter)>::type>::value)
std::cout<<"is const\n";
return 0;
}

http://coliru.stacked-crooked.com/a/253c6373befe8e50

我遇到这种行为是因为 declval<Container>()decltypestd::begin 表达. gcc 和 clang 都返回迭代器,这些迭代器在取消引用时会产生 const 引用。这可能是有道理的,因为右值引用通常绑定(bind)到您不想改变的过期对象。但是,我找不到任何关于此的文档来确定它是否由标准强制执行。我找不到 begin() 的任何相关重载或 Container::begin() 的 ref-qualified 重载.

更新:答案阐明了正在发生的事情,但交互可能很微妙,如下所示:

#include <iostream>
#include <string>
#include <vector>
#include <type_traits>

int main()
{
if(std::is_const<typename std::remove_reference<decltype(*begin(std::declval<std::vector<std::string>>()))>::type>::value)
std::cout<<"(a) is const\n";
if(!std::is_const<typename std::remove_reference<decltype(*std::declval<std::vector<std::string>>().begin())>::type>::value)
std::cout<<"(b) is not const\n";
if(!std::is_const<typename std::remove_reference<decltype(*begin(std::declval<std::vector<std::string>&>()))>::type>::value)
std::cout<<"(c) is not const\n";
return 0;
}

http://coliru.stacked-crooked.com/a/15c17b288f8d69bd

天真地,当::begin 只是根据调用 vector::begin 定义时,您不会期望 (a) 和 (b) 有不同的结果。然而,缺少采用非 const 右值引用并返回迭代器的 std::begin 重载(或返回 const_iterator 的 ref-qualified vector::begin 重载)恰恰导致了这种情况的发生。

最佳答案

正如您在 http://en.cppreference.com/w/cpp/iterator/begin 中看到的那样有趣的重载是:

template<class C> auto begin(C& c) -> decltype(c.begin());
template<class C> auto begin(const C& c) -> decltype(c.begin());

std::vector<int>&&只能绑定(bind)到第二个重载(因此返回 const_iterator )。

关于c++ - C++11标准中是否规定std::begin(Container&&)返回const_iterator?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39788176/

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