【问题标题】:Template class with template function具有模板功能的模板类
【发布时间】:2011-10-24 07:39:34
【问题描述】:

谁能说出这段代码有什么问题?

template<class X>
class C {
public:
    template<class Y> void f(Y); // line 4
};

template<class X, class Y>
void C<X>::f(Y y) { // line 8
    // Something.
}

int main() {
    C<int> c;
    char a = 'a';
    c.f(a);
    return 0;
}

编译:

$ g++ source.cpp 
source.cpp:8: error: prototype for ‘void C<X>::f(Y)’ does not match any in class ‘C<X>’
source.cpp:4: error: candidate is: template<class X> template<class Y> void C::f(Y)

现在我可以通过在第 4 行声明和定义函数来完成任务,但是与单独声明和定义函数相比,同时声明和定义函数的后果是什么? (这不是关于在头文件和源文件中声明函数的讨论)

注意:我见过this question,但似乎唯一让我感兴趣的部分被遗漏了=(

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    编译器已经告诉你答案了。类C是一个带参数的模板,而成员函数f是一个模板成员函数,同样的定义:

    template <class X>
    template <class Y>
    void C<X>::f(Y y)
    {
        // Something.
    }
    

    如果您在声明站点定义函数,您将隐式声明它inline;这实际上是唯一的区别。当然,可能会有风格上的考虑,例如永远不要将函数定义放在类定义中。

    正如您正确观察到的,您仍然需要在头文件中提供定义,因为您需要在使用模板时实例化模板,因此您需要访问所有定义.

    【讨论】:

    • 很好的答案,谢谢!还有一件事:为什么@“Johannes Schaub - litb”在注释中链接的问题的公认答案中说这种做法(至少我认为他指的是“模板模板”)是不正确的?
    • @Freitass:我不确定你指的是什么(你能更具体一点吗?),但链接的问题是关于 模板专业化,你是不适合你的情况。
    • 嗯,this 是答案,我问的是答案的第一行和第一块代码。
    • @Freitass:同样,这个答案是关于 specializing 模板参数(OP 想要专门化成员模板而不是类本身)。这对您有何影响?
    • 我只是想因为两者都与具有模板功能的模板类有关。感谢您的回答中的inline 部分(再次=D)。我对此一无所知。
    【解决方案2】:

    错误告诉你,你的代码应该是这样的:

    template<class X>
    class C {
    public:
        template<class Y> void f(Y); // line 4
    };
    
    template<class X> template<class Y>
    void C<X>::f(Y y) { // line 8
        // Something.
    }
    
    int main() {
        C<int> c;
        char a = 'a';
        c.f(a);
        return 0;
    }
    

    您的班级未定义为template&lt;class X, class Y&gt;

    【讨论】:

      【解决方案3】:

      顺便说一句,最好在模板参数列表中使用关键字“typename”而不是“class”。

      【讨论】:

      • 是的,我也读过。但是有这么多人使用类..我不想逆流而上(至少不是因为这个原因:P)
      • 这应该是评论,而不是答案。另外,我不同意或不同意你的观点,但你可能应该用一些事实来支持你的陈述,说明为什么使用“typename”比“class”更可取。
      • @andand:我完全同意。
      • 'int' 是一个类吗?不会。它会被接受为模板参数吗?是的。这是模棱两可的吗?是的。你能阻止它吗?是的。使用“类型名”。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-25
      相关资源
      最近更新 更多