2017-06-24 14 views
7

Tôi muốn kiểm tra xem loại có mục nhập trong std :: numeric_limits hay không. Khi loại là một mảng - (hoặc có lẽ không phải là một số?) Tôi nhận được một lỗi trình biên dịch. Điều này ngăn cản tôi phát hiện và phân nhánh dựa trên việc kiểu được hỗ trợ trong std :: numeric_limits. Tôi sẽ đánh giá cao bất kỳ cái nhìn sâu sắc nào ai cũng muốn chia sẻ.Phát hiện chuyên môn của std :: số :: loại <T> đối với một số loại số không T

// the following provokes compiler error on Clang 
// Function cannot return array type 'type' (aka 'char [20]') 
static_assert(
    ! std::numeric_limits<char[20]>::is_specialized, 
    "! std::numeric_limits<char[20]>::is_specialized" 
); 
// invokes static assert on compile as expected 
static_assert(
    std::numeric_limits<char[20]>::is_specialized, 
    "std::numeric_limits<char[20]>::is_specialized" 
); 
+1

Bạn có thể cho biết ví dụ về cách bạn muốn "phát hiện và phân nhánh" không? Tôi đoán một cái gì đó bên trong một mẫu, thay vì cho một loại cố định như 'char [20]', mà tất cả chúng ta đều biết câu trả lời? – aschepler

+1

Xác định "phát hiện và phân nhánh". Mục đích của 'static_assert' là, thực sự, để phát hành một lỗi biên dịch nếu xác nhận không thành công. Nếu bạn cần một kết quả khác, bạn phải giải thích nó là gì. –

Trả lời

2

Điều này xảy ra bởi vì nếu bạn có một cái nhìn bên trong std::numeric_limits hay hãy nhìn vào các tài liệu, bạn sẽ thấy tờ khai các phương pháp như sau

template<class T> 
class numeric_limits 
{ 
public: 
    static constexpr bool is_specialized = false; 
    static constexpr T min() noexcept; 
    static constexpr T max() noexcept; 
    static constexpr T lowest() noexcept; 

Ở đây bạn có thể thấy có những chức năng mà trở lại T theo giá trị và C++ không hỗ trợ các loại mảng trả về theo giá trị (xem Why doesn't C++ support functions returning arrays?)

Vì vậy, dòng sau sẽ không biên dịch

std::numeric_limits<char[20]>::is_specialized 

Và bất kỳ nỗ lực nào khác để kiểm tra trực tiếp xem is_specialized có hoạt động trực tiếp với SFINAE không biên dịch không. bản mẫu. Vì vậy, bạn sẽ cần phải kiểm tra các khái niệm đó được hỗ trợ cho std::numeric_limits (trong trường hợp này std::is_arithmetic)

Tuy nhiên tất cả các bạn cần làm ở đây để làm công việc này là để std::decay_t loại

std::numeric_limits<std::decay_t<char[20]>>::is_specialized 

Và bây giờ nó sẽ làm việc vì bạn đã phân rã rõ ràng kiểu mảng thành một con trỏ và có thể trả về từ hàm. Bạn có thể muốn thực hiện điều đó ngay từ đầu vì bạn không muốn vô tình gọi số std::numeric_limits::is_specialized cho loại không bị mục nát như const int&

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