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。
我很难理解为什么可以编译以下代码段。我有一个模板 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。