【问题标题】:Confusion in using templates in class在课堂上使用模板的困惑
【发布时间】:2017-04-27 10:43:56
【问题描述】:

我目前正在自学/学习泛型编程以及如何使用templates 在运行时声明数据类型。我理解了基本示例,您可以将变量设置为模板,以便以后可以创建任何数据类型,但这是我尝试使用类/向量的模板:

#include <string>
#include <vector>
#include <iostream>

using namespace std;

template <class T, class U>   
class CMap{ 
private:
    vector<T> keys;
    vector<U> values;

public:
    void insert(T key, U value){
        keys.push_back(key);
        values.push_back(value);
    }

    void get(int n){
        cout << keys[n] << " values ->" << values[n];
    }
};

int main(){
    CMap<string, int> grades;
    grades.insert("Jones", 12);
    grades.insert("Smith", 40);

    grades.get(0);
    cout << endl;
    grades.get(1);
    cout << endl;
}

我知道我们创建了 TU 作为模板,它们将进入 vector 数据类型。我也知道我们可以动态使用insert 方法,因为TU 是模板。

我不明白的:

当我宣布我的班级时,我被告知要添加以下 &lt;string, int&gt; 我不明白这是在做什么?它怎么知道第一个参数应该转到vector&lt;t&gt; keys&lt;&gt; 中的第二个参数应该转到vector&lt;u&gt; values - 如果这是它正在做的事情?

【问题讨论】:

  • 好吧,你已经给它们命名了——第一个是T,它接收string,第二个是U,它接收int
  • “如何使用模板在运行时声明数据类型” 是什么让您觉得模板可以做到这一点?
  • 什么令人困惑?它像函数和参数一样工作。你有一个模板,当你使用它时,你提供参数......它不会在运行时发生。
  • @luk32 参数。您为参数提供参数。 :)
  • 是的,是的,我的错,模板也是如此。我们用参数声明它们,并使用提供参数,以便用参数替换参数。 (希望我做对了=)

标签: c++ class templates vector


【解决方案1】:

当您使用语句CMap&lt;string, int&gt; grades; 时,您将创建CMap 类型的对象,其中T 的每次出现都被string 替换,U 的每次出现都被int 替换。

由于您的插入方法具有签名void insert(T key, U value),因此您新创建的对象将采用stringint 来替换TU,因为这是您在创建对象时提供的数据类型.

您可以对TU 使用您喜欢的任何数据类型,包括您自己的类。

【讨论】:

    【解决方案2】:

    让我们先弄清楚在 C++ 中声明模板是什么意思,因为似乎有些混乱。

    什么是模板

    模板是你用来创建类的东西,有点像类工厂。模板不是类也不是类型。

    您通过template&lt;class T, class U /* ... */&gt; 声明模板及其将采用的参数,类似于函数将值作为参数的方式。

    当您将类型作为模板参数传入时,您实例化模板,从而创建了一个类型。实例化模板时,您传入的类型将替换相同参数的出现,这与参数传递与函数的工作方式类似。

    template<class T>
    class MyTemplateClass
    {
    public:
        T member;
    };
    MyTemplateClass<int> var;
    

    在本例中,MyTemplateClass 是模板,它不是类型。

    MyTemplateClass&lt;int&gt; 一种类型,只有一个int类型的成员变量。我们说MyTemplateClass&lt;int&gt;MyTemplateClass实例化MyTemplateClass 中每次出现的 T 都将替换为 MyTemplateClass&lt;int&gt; 中的 int

    由于MyTemplateClass&lt;int&gt;只是一个类型,最后一行只是一个变量声明,因此var只是一个MyTemplateClass&lt;int&gt;类型的变量。

    这一切都发生在编译时,不是运行时。
    编译器确切地知道MyTemplateClass&lt;int&gt; 是什么,它确切地知道其中的类型,它确切地知道代码应该编译成什么。

    回答您的问题

    你的情况

    template<class T, class U>
    class CMap{ 
    private:
        vector<T> keys;
        vector<U> values;
    //...
    };
    

    实际上是在声明您有一个具有 2 个参数和 2 个成员变量的模板。 keys 的类型为 vector&lt;T&gt;,其中 T 是第一个模板参数,values 的类型为 vector&lt;U&gt;,其中 U 是第二个模板参数。

    CMap<string, int> grades;
    

    实际上是在声明一个变量grades,类型为CMap&lt;string, int&gt;

    CMap&lt;string, int&gt;CMap 的实例化,stringint 作为参数。

    grades.keys 的类型为 vector&lt;string&gt;grades.values 的类型为 vector&lt;int&gt;

    【讨论】:

    • 是的,但是它怎么知道 vector 键与 t 类匹配。如果我有更多私有变量并且我不希望它们成为模板怎么办
    • @jimmyspinner 按原样声明它们? int member2?
    猜你喜欢
    • 1970-01-01
    • 2021-09-09
    • 2021-11-05
    • 1970-01-01
    • 2019-05-13
    • 2015-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多