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

Posted

技术标签:

【中文标题】c ++:在完全定义类之前使用类作为模板参数【英文标题】:c++: use of class as template argument before class is fully defined 【发布时间】:2017-01-10 22:57:05 【问题描述】:

我很难理解为什么以下 sn-p 编译。我有一个模板类ptr_to_member<T>,它存储了一个指向T 成员函数的指针。然后我正在创建一个新类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();


【问题讨论】:

【参考方案1】:

在定义一个类时,该类可以像前向声明一样使用。由于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,了解有关何时可以使用和不能使用前向声明类型的更多信息。

【讨论】:

鉴于my_class 在其定义中是一个不完整的类型,我认为我只被允许使用指针或对它的引用,而不是任何方法。因此,如果我有一个指向 my_class 的指针,我将无法在定义 my_class 之前使用 my_class_ptr-&gt;f()。因此,我期望在 ptr_to_member 的构造函数中使用 &amp;T::f 会产生问题......我错过了什么? 本例中的模板是红鲱鱼。只有在类声明完成后才能查看方法定义。我认为this answer 可以比我在评论中更好地解释它。 谢谢,我想我现在明白了

以上是关于c ++:在完全定义类之前使用类作为模板参数的主要内容,如果未能解决你的问题,请参考以下文章

如何以模板类作为模板参数在模板类中正确定义模板函数

c ++:使用模板在类中定义可变长度数组

在成员变量中使用模板类作为模板模板参数时出错

C++11 ——— 可变参数模板

C++11 ——— 可变参数模板

C++11新特性:9—— C++11在函数模板和类模板中使用可变参数