c++: 在完全定义 class 之前使用 class 作为模板参数

c++: use of class as template argument before class is fully defined

我很难理解为什么可以编译以下代码段。我有一个模板 class ptr_to_member<T>,它存储指向 T 的成员函数的指针。然后我创建了一个新的 class my_class,它有一个 ptr_to_member<my_class>。鉴于 my_class 仍在定义中,我预计后者会导致编译错误。任何帮助表示赞赏。谢谢。

#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();

}

在定义 class 时,class 可以像前向声明一样使用。由于 ptr_to_member 仅使用指向 T 的指针,直到您实例化它的方法之一,所以它不会抱怨。尝试添加成员 T 而不是指针,您会发现它失败了。直观的理解是,你不需要知道 T 是什么就可以使用 T 的指针,只需要知道 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;
    }

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

有关何时可以和不可以使用前向声明类型的详细信息,请参阅 this answer