下面是相關的代碼的鏈接:在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