2013-07-19 28 views
10

Tôi có một lỗi biên dịch:mất vòng loại dễ bay hơi const

error C3848: expression having type 'const unicode::endian_swap<T>' 
      would lose some const-volatile qualifiers in order to call 
      'unsigned long unicode::endian_swap<T>::operator()(T &)' 

Các mô tả về lỗi này, Here, không thực sự giải thích những gì đang xảy ra.

Tôi không thể tạo lại lỗi trong mẫu nhỏ hơn, nhưng tôi có thể hiển thị bố cục cơ bản của lớp học.

template < typename T > 
struct endian_swap 
{ 
    endian_swap (void) {} 
    T operator() (T& _val) const { return _val >> 8 | _val << 8; } 
}; 

template < typename T > 
struct test 
{ 
    endian_swap<T> _swap; 

    virtual void do_it () const 
    { 
     unsigned short n = 0x1234; 
     unsigned short * _dest = &n; 

     *_dest++ = _swap(n); // <-- Error is here 
    } 
}; 

Lỗi xuất hiện sau khi thêm endian_swap làm thành viên. Lớp thực tế có nguồn gốc từ std::codecvt và được cài đặt vào một std::locale.

Ai đó có thể giải thích rõ hơn về lỗi so với trang web ở trên.

Chỉnh sửa: Mã Thực tế:

template < typename T, size_t N = sizeof(T) > struct endian_swap 
{ 
    endian_swap (void) {}; 
    T operator() (const T _val) const { return _val }; 
}; 
template < typename T > struct endian_swap< T, 2 > 
{ 
    endian_swap (void) {} 
    T operator() (const T _val) const { return _val >> 8 | _val << 8; } 
}; 
template < typename T > struct endian_swap< T, 4 > 
{ 
    endian_swap (void) {}; 
    T operator() (const T _val) const { return (_val >> 24) | ((_val & 0x00ff0000) >> 8) | ((_val & 0x0000ff00) << 8) | (_val << 24) }; 
}; 

Cập nhật: Tìm thấy nó! Hãy xem kỹ mẫu ở trên và xem bạn có thấy nó không.

+0

Chức năng hoán đổi cuối cùng của bạn không hoạt động ngay nếu 'T' được ký. Ngoài ra, không có lý do chính đáng để lấy '_val' bằng cách tham chiếu. –

+0

+1 cho "thường google mang lại cho tôi câu trả lời"! –

+0

@BenVoigt Đó là do thiết kế, tất cả các thông số mẫu được buộc phải bỏ dấu. – Twifty

Trả lời

5

Làm cách nào bạn tạo mẫu nhanh. Bản trình bày của bạn về số endian_swap sử dụng loại T và bạn vượt qua nó unsigned short. Trừ khi Tunsigned short, bạn sẽ cần chuyển đổi và kết quả của chuyển đổi là tạm thời, không thể liên kết với tham chiếu không phải const.

Bạn không cung cấp SSCCE, vì vậy thật khó để nói. Tuy nhiên, thông báo lỗi bạn gửi đề cập đến một cuộc gọi đến unsigned long unicode::endian_swap<T>::operator()(T &); hoặc endian_swap được khởi tạo cho unsigned long (trong đó trường hợp, đi qua một unsigned short sẽ đòi hỏi một tạm thời), hoặc mã bạn được đăng không phải là mã đã kích hoạt lỗi.

+0

Kiểu dữ liệu thực tế là 'std :: codecvt :: intern_type' được đặt thành' unsigned short' khi tạo. – Twifty

+0

Hãy cho tôi một số đề xuất để thử. Kéo tóc của tôi qua cái này. :/ – Twifty

+0

Nếu đây là trường hợp thì trình chẩn đoán của trình biên dịch vô vọng sẽ bỏ lỡ dấu. –