2017-10-18 22 views
11

Tôi đã gặp một vấn đề với g ++ với upcasting của một con trỏ thành viên trong một bối cảnh constexpr sử dụng static_cast. Xem ví dụ về mã.static_cast của con trỏ thành viên trong ngữ cảnh constexpr trên g ++

Khi biên dịch bằng g ++ phiên bản 6.3 và 7.0, chúng cung cấp lỗi biên dịch cho biết reinterpret_cast không phải là biểu thức liên tục. Trong khi phiên bản 4.0 clang không có lỗi, mà tôi nghĩ là chính xác vì không có reinterpret_cast ở đây.

Đây có phải là lỗi trong g ++ hoặc clang không? Hành vi chính xác là gì?

struct Base {}; 

struct Derived : Base 
{ 
    int i; 
}; 

struct Ptr 
{ 
    constexpr Ptr(int Derived::* p) : p(static_cast<int Base::*>(p)){} 
    int Base::* p; 
}; 

constexpr Ptr constexpr_ptr(&Derived::i); 

biên dịch ra

g++ -c -std=c++14 test.cpp 
test.cpp:17:40: in constexpr expansion of ‘Ptr(&Derived::i)’ 
test.cpp:11:41: error: a reinterpret_cast is not a constant expression 
constexpr Ptr(int Derived::* p) : p(static_cast<int Base::*>(p)){} 
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~ 
+1

Điều này thực sự không phải là một sự u ám. –

Trả lời

3

GCC lẽ misapprehends [expr.static.cast]/12, cho phép dàn diễn viên của bạn và lưu ý rằng

Nếu lớp B chứa các thành viên ban đầu, hoặc là một cơ sở hoặc lớp có nguồn gốc của lớp chứa thành viên ban đầu, con trỏ kết quả đến các điểm thành viên đối với thành viên ban đầu. Nếu không, hành vi là không xác định.

Base thực sự là cơ sở của lớp chứa thành viên, hành vi cần được xác định và hàm tạo gọi biểu thức không đổi.

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