【问题标题】:Class template interaction类模板交互
【发布时间】:2014-03-22 04:35:50
【问题描述】:

我实际上相当确定我的问题的答案可以在之前创建的线程之一中找到。特别是Where and why do I have to put the "template" and "typename" keywords?,它对模板/类型名消歧有很好的解释。然而,我不知所措,因为我实际上无法将这个概念扩展到我的代码,即相互交互的类模板。

在这个线程中,我想我看到的错误与我在代码中遇到的错误相同。为什么答案是使用 A<B> 定义 typedef,其中 B 是类,而不是 A<T>,其中 T 是我们实际想要的类型名模板。

尽管如此,我尝试了这些选项都无济于事。这是代码。感谢您的帮助。

#include "testTemplateA.h"
template<typename A>
class testTemplateB {
public:
    // none of these work
    typedef testTemplateA<A> templateType;
    typedef typename testTemplateA<A> templateType;
    typedef typename testTemplateA<testTemplateB> templateType;

    testTemplateB(templateType& TA) {}

    ~testTemplateB(void) {}
};

#include "testTemplateB.h"
template<typename A>
class testTemplateA
{
public:
    testTemplateA(void) {}

    ~testTemplateA(void) {}

    void callUponB(void) {
        testTemplateB<A> g = testTemplateB<A>(this);
    }



};

【问题讨论】:

    标签: c++ templates typename class-template


    【解决方案1】:

    这看起来更像是一个循环依赖问题而不是模板语法问题。只要您可以定义一个类而另一个不完整,您就可以执行以下操作:

    // Begin testTemplateA.h
    #ifndef TEST_TEMPLATE_A_H
    #define TEST_TEMPLATE_A_H
    
    template<typename A>
    class testTemplateA
    {
    public:
        testTemplateA(void) {}
    
        ~testTemplateA(void) {}
    
        void callUponB(void); // Can't be defined here!
    };
    
    #include "testTemplateB.h"
    
    template<typename A>
    void testTemplateA<A>::callUponB(void) {
        testTemplateB<A> g = testTemplateB<A>(this);
    }
    
    #endif
    // End testTemplateA.h
    
    // Begin testTemplateB.h
    // Yes, the include is outside the define guard.
    #include "testTemplateA.h"
    
    #ifndef TEST_TEMPLATE_B_H
    #define TEST_TEMPLATE_B_H
    
    template<typename A>
    class testTemplateB {
    public:
        typedef testTemplateA<A> templateType;
    
        testTemplateB(templateType& TA) {}
    
        ~testTemplateB(void) {}
    };
    
    #endif
    // End testTemplateB.h
    

    如果源文件只包含 testTemplateA.h,它将看到 testTemplateA 的类模板定义,然后包含 testTemplateB.h 的全部内容,然后在 testTemplateA.h 中看到依赖于 testTemplateB 的成员定义.如果一个源文件只包含 testTemplateB.h,它将立即以 testTemplateA.h 开头,它仍然会在中间包含 testTemplateB.h 并获得相同的结果。如果源文件以任一顺序包含两者,则第二个将无效,因为两者都已包含。

    您只需要在名称前加上typename 关键字,至少包含一个:: 令牌。

    另一件事:您的构造函数testTemplateB(templateType&amp; TA); 需要一个引用,但您的语句testTemplateB&lt;A&gt; g = testTemplateB&lt;A&gt;(this); 传递了指针值this

    【讨论】:

    • 我一读到通函,我就想它可能会包含答案,我认为确实如此。但是,如果您愿意,我可能需要更多解释。原型和实际方法的分离类似于头/目标文件的分离,但有人告诉我在使用类模板时不能使用这种风格。您是否愿意解释为什么在这种情况下允许这样做?
    • @user3417339:可以在类外定义类模板的成员(或模板成员)。它只需要在包含的头文件中,而不是在其他源文件不可见的源文件中。
    【解决方案2】:

    问题来了

    typedef testTemplateA<A> templateType;
    

    您正在使用类模板创建模板类

    template<typename A>
    class testTemplateA
    

    在创建模板类时,您需要提供实际类型。所以应该是这样的,

    typedef testTemplateA<< testTemplateB<int >> templateType;
    

    如果期望 T 始终是一个类,建议使用“class”,如果其他类型(int、char*、float)则使用“typename”无论如何)可能是预期的。将其视为使用提示。

    【讨论】:

    • 不,testTemplateA&lt;A&gt; 是有效类型(取决于模板参数A)。
    • 同意!!但由于循环依赖,编译时报错。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多