2011-01-13 21 views
7

Thông thường, nếu tôi cần phát hiện xem loại có là const Tôi chỉ sử dụng boost::is_const. Tuy nhiên, tôi gặp rắc rối khi cố gắng để phát hiện các const-ness của một loại lồng nhau. Hãy xem xét các đặc điểm mẫu sau đây, mà là chuyên ngành với nhiều loại const:Phát hiện const-ness của kiểu lồng nhau

template <class T> 
struct traits 
{ 
    typedef T& reference; 
}; 

template <class T> 
struct traits<const T> 
{ 
    typedef T const& reference; 
}; 

Vấn đề là boost::is_const dường như không phát hiện rằng traits<const T>::reference là một loại const.

Ví dụ:

std::cout << std::boolalpha; 
std::cout << boost::is_const<traits<int>::reference>::value << " "; 
std::cout << boost::is_const<traits<const int>::reference>::value << std::endl; 

đầu ra này: false false

Tại sao không cho nó xuất false true?

Trả lời

13

Vì tham chiếu không phải là const, nên đó là kiểu tham chiếu đó là const. Phải, không có tham chiếu const. Vì vậy, hãy tưởng tượng rằng tham chiếu là một con trỏ, sau đó sự khác biệt dễ hiểu hơn: int const* không const, int *const là const.

Sử dụng remove_reference để có được những kiểu const thực tế:

cout << boost::is_const< 
      boost::remove_reference<int const&>::type>::value << '\n'; 
4

Vâng, bạn đã lưu ý rằng is_const<int const&>::value là tương tự như vậy sai? Nó là. Một cái gì đó như thế này nên là một trong những điều đầu tiên bạn cố gắng để gỡ lỗi các mẫu như thế này. Một điều bạn có thể tận dụng là một máy in loại:

template < typename T > struct print;

Khi bạn nhanh chóng mà bạn sẽ nhận được bất cứ điều gì T là trong đầu ra lỗi, với hầu hết các trường.

Hãy thử điều này để giải quyết vấn đề hiện tại của bạn:

is_const< remove_reference< traits<int const>::reference >::type >::value

+1

s/is_cost/is_const / –

6

Bởi vì tài liệu tham khảo không const. :)

Bạn có một chế độ xem lại (xem xét tương tự thô, int const*, trong đó pointee int có ngữ cảnh const, nhưng bản thân con trỏ thì không). Tiêu chuẩn kết hợp các thuật ngữ ở đây, nhưng tôi tránh thuật ngữ "const ref" gây hiểu lầm cao.

Tài liệu tham khảo vốn không thay đổi vì chúng chỉ có thể được khởi tạo và sau đó không bị ràng buộc lại, nhưng điều đó không làm cho chúng const.

Bạn có thể xóa tham chiếu khỏi loại với boost::remove_reference (như được chỉ ra trong các câu trả lời khác).