2015-06-07 10 views
7

W poniższym kodzie użyłem std::remove_const i std::remove_reference ale w innej kolejności w dwóch przypadkach, które dają różne wyniki:Dlaczego używanie std :: remove_reference i std :: remove_const w innej kolejności daje inne wyniki?

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

using namespace std; 

int main() 
{ 
    vector<string> ar = {"mnciitbhu"}; 
    cout<<boolalpha; 
    cout<<"First case : "<<endl; 
    for(const auto& x : ar) 
    { 
     // Using std::remove_const and std::remove_reference 
     // at the same time 
     typedef typename std::remove_const< 
      typename std::remove_reference<decltype(x)>::type>::type TT; 
     cout<<std::is_same<std::string, TT>::value<<endl; 
     cout<<std::is_same<const std::string, TT>::value<<endl; 
     cout<<std::is_same<const std::string&, TT>::value<<endl; 
    } 
    cout<<endl; 
    cout<<"Second case : "<<endl; 
    for(const auto& x : ar) 
    { 
     // Same as above but the order of using std::remove_reference 
     // and std::remove_const changed 
     typedef typename std::remove_reference< 
      typename std::remove_const<decltype(x)>::type>::type TT; 
     cout<<std::is_same<std::string, TT>::value<<endl; 
     cout<<std::is_same<const std::string, TT>::value<<endl; 
     cout<<std::is_same<const std::string&, TT>::value<<endl; 
    } 
    return 0; 
} 

wyjście jest:

First case : 
true 
false 
false 

Second case : 
false 
true 
false 

Sprawdź na Coliru Viewer

Moje pytanie brzmi: dlaczego używanie różnych ustawień w różnych sytuacjach daje różne wyniki? Ponieważ usuwam zarówno odniesienie, jak i wartość odniesienia, czy wynik nie powinien być taki sam?

+0

[Wniosek] (http://en.cppreference.com/w/cpp/types/remove_cv) będzie dobry start, a nawet ma bardzo podobny przykład, ale ze wskaźnikiem. – chris

Odpowiedz

16

remove_const usunie tylko kwalifikator top-levelconst, jeśli taki istnieje. W const std::string&, const nie jest najwyższym poziomem, dlatego zastosowanie remove_const nie ma na niego wpływu.

Po odwróceniu zamówienia i zastosowaniu najpierw remove_reference, otrzymany typ to const string; teraz wersja const jest na najwyższym poziomie, a kolejna aplikacja remove_const usunie kwalifikator const.

Powiązane problemy