【问题标题】:Instantiate a template for a vector为向量实例化模板
【发布时间】:2011-08-25 05:21:35
【问题描述】:
#include <iostream>
#include <vector>
using namespace std;

template <typename nameOfTheVariableTypeA, 
      typename nameOfTheVariableTypeB> nameOfTheVariableTypeB functionX 
                                               (nameOfTheVariableTypeA argA,
                                               (nameOfTheVariableTypeB argB)
{
    nameOfTheVariableTypeA tempArgA;
    nameOfTheVariableTypeB tempArgB;

    argA.push_back(22);

    tempArgA = argA;
    cout << "\ntempArgA: " << tempArgA[0] << "\n";

    tempArgB = argB;
    cout << "\ntempArgB: " << tempArgB << "\n";

    return tempArgB;
}

int main ()
{
    functionX (12, 12.4567);

    vector <int> f;
    functionX (f, 12.4567);

    return 0;
}

来自模板书: An attempt to instantiate a template for a type that doesn't support all the operations used within it will result in a compile-time error.

我收到的上述代码的错误是:

  1. error: request for member ‘push_back’ in ‘argA’, which is of non-class type ‘int’

  2. error: subscripted value is neither array nor pointer

我错过了什么?

【问题讨论】:

  • 也许代码不应该编译?它可能只是对书中所讲内容的一个演示。
  • @In silico 不,那个代码是“我的”,我想了解错误的原因。

标签: c++ templates vector


【解决方案1】:

首先,有一个多余的括号:

template <typename nameOfTheVariableTypeA,  
      typename nameOfTheVariableTypeB> nameOfTheVariableTypeB functionX  
                                               (nameOfTheVariableTypeA argA, 
                                              /*(*/nameOfTheVariableTypeB argB) 
// Note: extra parenthesis not needed here -----^ 
{

假设这只是一个错字,让我们看看第一次调用functionX():

functionX(12, 12.4567);  

现在,模板函数要求在调用它们之前指定所有模板参数。但在某些情况下,编译器可以推断出 nameOfTheVariableTypeA 和 nameOfTheVariableTypeB 所需的类型,以便函数调用正常工作。

在这种情况下,12 是一个整数文字,因此它的类型为 int。 12.4567 是一个浮点字面量,因此它的类型为 double。因此,在functionX() 内,nameOfTheVariableTypeA 的类型为int,nameOfTheVariableTypeB 的类型为double。

现在所有模板参数都已指定(在本例中为推导),编译器可以实例化模板函数。也就是说,编译器会创建一个如下所示的函数:

// Hypothetical function generated by the compiler
double functionX_int_double(int argA, double argB)  
{  
    int tempArgA;  
    double tempArgB;  
    // ...

就好像编译器简单地将nameOfTheVariableTypeA 和nameOfTheVariableTypeB 替换为推导的类型。显然,参数argA 和变量tempArgA 的类型为int。第一个错误是因为int 没有名为push_back() 的类成员函数。这与这不起作用的原因相同:

int i = 20;
i.push_back(22);

您还会收到第二个错误,因为没有为ints 定义下标运算符[]。同样,这与它不起作用的原因相同:

int j = 21;
cout << j[0];

请注意,此类信息可以从编译器错误本身中收集。请务必阅读它们!

【讨论】:

  • +1:我没有看到多余的括号,可能是因为类型名称不必要的长...
  • @Rene 输入解释变量名称是一种有益的做法。
  • @Anisha Kaul:不言自明的名字很好,但不要过分使用它们。 :-) 简洁;例如,TypeA 和 TypeB 具有相同的描述性,但键入时需要的工作量要少得多。
【解决方案2】:

在您第一次致电functionX:

functionX (12, 12.4567);

模板中的nameOfTheVariableTypeA 类型将被推断为int。显然int 类型不支持push_back() 或operator[]。

【讨论】:

    【解决方案3】:

    电话

    functionX (12, 12.4567);
    

    用(int, double) 参数实例化一个函数。 int argA 既没有 push_back() 方法也没有数组索引运算符。所以你也不能使用tempArgA[0]。

    【讨论】:

      【解决方案4】:

      带有模板专业化的完整代码:)。正如其他人所说,“int”没有 push_back 函数,因此您需要专门的实现。

      模板 &lt 类型名称 nameOfTheVariableTypeA, 类型名称 nameOfTheVariableTypeB &gt nameOfTheVariableTypeB functionX (nameOfTheVariableTypeA argA,nameOfTheVariableTypeB argB) { nameOfTheVariableTypeA tempArgA; nameOfTheVariableTypeB tempArgB; argA.push_back(22); tempArgA = argA; cout &lt&lt "\ntempArgA: " &lt&lt tempArgA[0] &lt&lt "\n"; /*tempArgB = argB; cout &lt&lt "\ntempArgB: " &lt&lt tempArgB &lt&lt "\n";*/ 返回 tempArgB; } 模板 &lt &gt 浮点函数X &lt int,float &gt (int argA,float argB){ int tempArgA; int tempArgB; tempArgA = argA; cout &lt&lt "\ntempArgA: " &lt&lt tempArgA &lt&lt "\n"; 返回 tempArgB; } 主函数() { 函数X &lt int,float &gt(12, 12.4567); 向量 &lt int &gt f; 函数X &lt 向量 &lt int &gt , float &gt (f, 12.4567); 返回0; }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多