2017-01-10 12 views
5

Tôi đang gặp khó khăn trong việc hiểu lý do đoạn mã sau biên dịch. Tôi có một lớp mẫu ptr_to_member<T> lưu trữ con trỏ tới chức năng thành viên của T. Sau đó tôi tạo một lớp mới my_class có một số ptr_to_member<my_class>. Tôi mong đợi sau này gây ra một lỗi biên dịch cho rằng my_class vẫn đang được xác định. Bất kỳ trợ giúp được đánh giá cao. Cảm ơn bạn.C++: sử dụng lớp làm đối số mẫu trước khi lớp học được xác định đầy đủ

#include <iostream> 

// this class simply stores a pointer to a member function of T 
template <class T> 
struct ptr_to_member { 

    using ptr_type = void (T::*)(); 
    ptr_type m_ptr; 

    ptr_to_member() 
    : m_ptr(&T::f){} 

    auto get_ptr() const { 
     return m_ptr; 
    } 
}; 

// my_class has a ptr_to_member<my_class> 
class my_class { 

    ptr_to_member<my_class> m_ptr_to_member; // why does this compile? 

public: 

    void g() { 
     auto ptr = m_ptr_to_member.get_ptr(); 
     (this->*ptr)(); 
    } 

    void f() { 
     std::cout << "f" << std::endl; 
    } 
}; 

int main() { 

    my_class x; 
    x.g(); 

} 

Trả lời

0

Khi xác định một lớp, lớp đó có thể được sử dụng như thể nó được chuyển tiếp khai báo. Vì ptr_to_member chỉ sử dụng con trỏ đến T cho đến khi bạn khởi tạo một trong các phương pháp của nó, nó không khiếu nại. Hãy thử thêm một thành viên T thay vì một con trỏ và bạn sẽ thấy rằng nó không thành công. Cách trực quan để nhìn thấy nó là bạn không cần phải biết những gì T là sử dụng một con trỏ của T, chỉ có T là một loại. Con trỏ hành xử theo cùng một cách bất kể những gì họ trỏ đến cho đến khi bạn dereference chúng.

template <class T> 
struct ptr_to_member { 

    using ptr_type = void (T::*)(); 
    ptr_type m_ptr; 

    ptr_to_member() 
     : m_ptr(&T::f) {} 

    auto get_ptr() const { 
     return m_ptr; 
    } 

    T member; // Add this and see that it fails to compile 
}; 

Xem this answer để biết thêm thông tin về thời điểm bạn có thể và không thể sử dụng các loại được khai báo chuyển tiếp.

+0

Cho rằng 'my_class' là một loại không đầy đủ trong định nghĩa của nó, tôi nghĩ rằng tôi chỉ được phép sử dụng con trỏ hoặc tham chiếu đến nó và không phải bất kỳ phương pháp nào. Vì vậy, nếu tôi có một con trỏ tới 'my_class', tôi sẽ không thể sử dụng' my_class_ptr-> f() 'trước khi' my_class' được định nghĩa. Do đó tôi đã hy vọng rằng việc sử dụng '& T :: f' trong hàm tạo' ptr_to_member' sẽ tạo ra một vấn đề ... tôi đang thiếu gì? – linuxfever

+0

Mẫu trong trường hợp này là cá trích đỏ. Định nghĩa phương thức chỉ được xem xét sau khi khai báo lớp kết thúc. Tôi nghĩ rằng [câu trả lời này] (http://stackoverflow.com/a/13095136/7359094) có thể giải thích nó tốt hơn tôi có thể trong một bình luận. –

+0

Cảm ơn bạn, tôi nghĩ rằng tôi nhận được nó ngay bây giờ – linuxfever

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