2015-06-07 16 views
7

Trong đoạn mã sau tôi đã sử dụng std::remove_conststd::remove_reference nhưng trong thứ tự khác nhau trong hai trường hợp mà đang đưa ra kết quả khác nhau:Tại sao sử dụng std :: remove_reference và std :: remove_const theo thứ tự khác nhau tạo ra các kết quả khác nhau?

#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; 
} 

Đầu ra là:

First case : 
true 
false 
false 

Second case : 
false 
true 
false 

Kiểm tra trên Coliru Viewer

Câu hỏi của tôi là tại sao sử dụng std::remove_conststd::remove_reference theo thứ tự khác nhau tạo ra các kết quả khác nhau? Vì tôi đang xóa cả tham chiếu và const -ness, nên kết quả không giống nhau?

+0

[Tham chiếu này] (http://en.cppreference.com/w/cpp/types/remove_cv) sẽ là một khởi đầu tốt và thậm chí có một ví dụ rất giống với một con trỏ. – chris

Trả lời

16

remove_const sẽ chỉ xóa một vòng loại top-levelconst nếu có. Trong const std::string&, số const không phải là cấp cao nhất, do đó việc áp dụng remove_const không ảnh hưởng đến nó.

Khi bạn đảo ngược thứ tự và áp dụng remove_reference đầu tiên, loại kết quả là const string; hiện tại, const là cấp cao nhất và ứng dụng tiếp theo là remove_const sẽ xóa vòng loại const.

Các vấn đề liên quan