2013-04-08 54 views
14

Tại sao std::remove_const không chuyển đổi const T& thành T&? Ví dụ thừa nhận chứ không phải giả tạo này chứng tỏ câu hỏi của tôi:std :: remove_const với tham chiếu const

#include <type_traits> 

int main() 
{ 
    int a = 42; 
    std::remove_const<const int&>::type b(a); 

    // This assertion fails 
    static_assert(
     !std::is_same<decltype(b), const int&>::value, 
     "Why did remove_const not remove const?" 
    ); 

    return 0; 
} 

Các trường hợp trên là trivially dễ dàng để sửa chữa, do đó, bối cảnh, hãy tưởng tượng như sau:

#include <iostream> 

template <typename T> 
struct Selector 
{ 
    constexpr static const char* value = "default"; 
}; 

template <typename T> 
struct Selector<T&> 
{ 
    constexpr static const char* value = "reference"; 
}; 

template <typename T> 
struct Selector<const T&> 
{ 
    constexpr static const char* value = "constref"; 
}; 

int main() 
{ 
    std::cout 
     << Selector<typename std::remove_const<const int&>::type>::value 
     << std::endl; 

    return 0; 
} 

Trong ví dụ trên, tôi mong đợi reference được hiển thị, thay vì constref.

+0

Hãy nhớ rằng, không có điều gì như tham chiếu const, chỉ tham chiếu đến const. – xaxxon

Trả lời

13

std::remove_const loại bỏ cấp cao nhấtconst -yêu cầu. Trong const T&, tương đương với T const&, trình độ không phải là cấp cao nhất: trên thực tế, nó không áp dụng cho tham chiếu (điều đó sẽ là vô nghĩa, vì tham chiếu không thay đổi theo định nghĩa), nhưng đối với loại được tham chiếu.

Bảng 52 tại Khoản 20.9.7.1 của C++ 11 Chỉ định tiêu chuẩn, về std::remove_const:

Loại thành viên typedef sẽ đặt tên cho loại giống như T ngoại trừ việc bất kỳ top-level const -qualifier đã được gỡ bỏ. [Ví dụ: remove_const<const volatile int>::type đánh giá để volatile int, trong khi remove_const<const int*>::type đánh giá để const int*. - cuối dụ]

Để dải const đi, trước tiên bạn phải áp dụng std::remove_reference, sau đó áp dụng std::remove_const, và sau đó (nếu muốn) áp dụng std::add_lvalue_reference (hoặc bất cứ điều gì là thích hợp trong trường hợp của bạn).

LƯU Ý: Như Xeo đề cập trong các bình luận, bạn có thể xem xét using an alias template such as Unqualified để thực hiện hai bước đầu tiên, ví dụ lột bỏ sự tham khảo, sau đó lột bỏ sự const - trình độ chuyên môn (và volatile-).

+1

Hai số đầu tiên thường được nhóm lại với nhau dưới một bí danh 'Unqualified '. – Xeo

+0

@Xeo: Đã chỉnh sửa, cảm ơn bạn. –

+0

Ah, tôi hiểu rồi. Cảm ơn rất nhiều vì lời giải thích. :) – dafrito

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