下面是相关的代码的链接:在C + 11标准中指定std :: begin(Container &&)是否返回const_iterator?
#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>()
的这种行为在decltype
表达std::begin
。 gcc和clang都会返回在解引用时产生const引用的迭代器。这可能是有道理的,因为r值引用通常绑定到你不想改变的到期对象。但是,我找不到任何有关此文件的文件,以确定它是否符合标准。我无法找到begin()
或Container::begin()
的重新认证的过载。
更新:答案澄清所发生的事情,但是,如下面所示的相互作用可以是微妙:
#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
天真,你不会期待不同的结果(一)和(b) when :: begin只是通过调用vector :: begin来定义的。然而,没有使用非const r值引用和返回迭代器(或ref-qualified vector :: begin重载const_iterator重载)的std :: begin重载会导致这种情况发生。
这是有道理的,但它是一个有点令人惊讶的是'decltype(*开始(declval <性病::矢量>()))'是一个常量性病: :string&当矢量和字符串都不是常量时。如果使用vector :: begin,则结果将是字符串&! With :: begin你需要传递vector&declval以避免获得const string&。 [此链接](http://coliru.stacked-crooked.com/a/15c17b288f8d69bd)说明了微妙之处。 –
authentec
这应该是std :: begin而不是:: begin以上。 – authentec