模板函数中的 C++11 for 循环

C++11 for loop in a Template Function

本文关键字:C++11 for 循环 函数      更新时间:2023-10-16

我正在尝试编写一个可以在控制台上打印数据的函数。该函数将被模板化,因为它应该接受不同类型的数据。

代码如下所示:

template<typename DataType>
void PrintData(DataType *X)
{
    for (DataType Data : X)
    {
        cout << Data << "t";
    }
    cout << endl;
}
int main()
{
    int nArray[7] = { 7, 5, 4, 3, 9, 8, 6 };
    double dArray[5] = { 4.3, 2.5, -0.9, 100.2, 3.0 };
    PrintData(nArray);
    PrintData(dArray);
    system("pause");
    return EXIT_SUCCESS;
}

我收到一个错误,即变量数据在模板化函数 PrintData 中未声明。

error C2065: 'Data' : undeclared identifier 
error C3312: no callable 'begin' function found for type 'double *'    
error C3312: no callable 'begin' function found for type 'int *'    
error C3312: no callable 'end' function found for type 'double *'    
error C3312: no callable 'end' function found for type 'int *'  

任何帮助将不胜感激。谢谢

假设您已经包含了iostream头文件和using namespace std;指令。那么你的问题是:

  1. 您不应该使用 DataType * .您的代码使X成为指针,这与数组不同。请改用DataType const&DataType&&
  2. 您必须包含 iterator 头文件,该文件为 C 样式数组提供beginend函数。

以下代码对我有用。

#include <iostream>
#include <iterator>
using namespace std;
template<typename DataType>
void PrintData(DataType const& X)
{
    for (auto Data : X)
    {
        cout << Data << "t";
    }
    cout << endl;
}
int main()
{
    int nArray[7] = { 7, 5, 4, 3, 9, 8, 6 };
    double dArray[5] = { 4.3, 2.5, -0.9, 100.2, 3.0 };
    PrintData(nArray);
    PrintData(dArray);
    return EXIT_SUCCESS;
}

正如Igor Tandetnik所评论的那样,如果您想引用数组的大小,则可以使用template<struct DataType, size_t N>

更新:

  1. 对于template<struct DataType>DataType *XDataType被推导出为intdoubleX是一个不是容器的指针。
  2. 对于template<struct DataType, size_t N>DataType (&X)[N]DataType被推导出为intdoubleX是一个可以与基于范围的for循环一起使用的数组。
  3. 对于template<struct DataType>DataType&& XDataType const& XDataType被推导为int[7]double[5]X也是一个数组。

问题是你传递的是数组的名称(例如,nArray ),基本上这只是指向第一个元素的指针。但是,新式for循环需要一些可以调用beginend的东西 - 一个范围。

以下更改使其通过使用vector而不是数组来工作。请注意,否则几乎没有差异,而且一般来说,在当代C++中使用 C 样式数组的理由很少。

#include <iostream>                                                                                                                                                                                          
#include <vector>
using namespace std;
template<typename DataType>
void PrintData(const DataType &X)
{
    for (const auto &Data : X)
    {
        cout << Data << "t";
    }
    cout << endl;
}
int main()
{
    vector<int> nArray = { 7, 5, 4, 3, 9, 8, 6 };
    vector<double> dArray = { 4.3, 2.5, -0.9, 100.2, 3.0 };
    PrintData(nArray);
    PrintData(dArray);
    system("pause");
    return EXIT_SUCCESS;

您有一些问题:

1) 数据类型必须是容器。因此,请尝试使用:

std::vector<int> nArray = { 7, 5, 4, 3, 9, 8, 6 };
std::vector<double> dArray = { 4.3, 2.5, -0.9, 100.2, 3.0 };

2)您不会更改容器。最好通过常量引用传递容器:

template<typename DataType>
void PrintData(const DataType & X);

3)像这样更改循环:

for (const auto & value : X) {
    std::cout << value << "t";
}

代码示例:

#include <iostream>
#include <vector>
template<typename DataType>
void PrintData(const DataType & X) {
    for (const auto & value : X) {
        std::cout << value << "t";
    }
    std::cout << std::endl;
}
int main() {
    std::vector<int> nArray = { 7, 5, 4, 3, 9, 8, 6 };
    std::vector<double> dArray = { 4.3, 2.5, -0.9, 100.2, 3.0 };
    PrintData(nArray);
    PrintData(dArray);
    return 0;
}

正如伊戈尔所建议的那样,如果你想使用DataType *那么你需要做这样的事情

#include <iostream>
#include <iterator>
using namespace std;
template <typename DataType, size_t N> 
void PrintData(DataType (&X)[N])
{
    for (auto i : X)
        cout << i << "t";
    cout << endl;
}
int main()
{    
    int nArray[7] = { 7, 5, 4, 3, 9, 8, 6 };
    double dArray[5] = { 4.3, 2.5, -0.9, 100.2, 3.0 };
    PrintData(nArray);
    PrintData(dArray);
    return EXIT_SUCCESS;
}

输出

7   5   4   3   9   8   6   
4.3 2.5 -0.9    100.2   3   

解释:

如果您看到 void PrintData(int* nArray); & void PrintData(int (&nArray)[7] );是类似的声明,除了秒一告诉数组在哪里结束。

模板功能

template <typename DataType, size_t N> 
void PrintData(DataType (&X)[N])

被推算为'

void PrintData(int (&nArray)[7] )

你也可以写

void PrintData(int (&nArray)[7] )
{
    for (auto i : nArray)
        cout << i << "t";
    cout << endl;
}