简体   繁体   English

C ++ 11 for Template函数中的循环

[英]C++11 for loop in a Template Function

I am trying to write a function which would Print Data on the console. 我正在尝试编写一个在控制台上打印数据的功能。 The function is to be templated as it should accept different types of Data. 该函数是模板化的,因为它应该接受不同类型的数据。

The code is as shown below: 代码如下所示:

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;
}

I get an error that variable Data is undeclared in the templated function PrintData. 我得到一个错误,即模板化函数PrintData中的变量Data未声明

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 *'  

Any help would be appreciated. 任何帮助,将不胜感激。 Thanks 谢谢

Assuming you have included the iostream header file and the using namespace std; 假设您已经包含了iostream头文件和using namespace std; directive. 指示。 Then your problems are: 那么你的问题是:

  1. You should not use DataType * . 您不应该使用DataType * Your code makes X a pointer, which is different from array. 你的代码使X成为一个指针,它与数组不同。 Use DataType const& or DataType&& instead. 请改用DataType const&DataType&&
  2. You have to include the iterator header file which provides the begin and end function for C-style array. 您必须包含iterator头文件,该文件为C样式数组提供beginend函数。

The following code works for me. 以下代码适用于我。

#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;
}

As commented by Igor Tandetnik, you may use template<struct DataType, size_t N> if you want to refer the size of the array. 正如Igor Tandetnik评论的那样,如果要引用数组的大小,可以使用template<struct DataType, size_t N>

Update: 更新:

  1. With template<struct DataType> and DataType *X , DataType is deduced as int and double , and X is a pointer which is not a container. 使用template<struct DataType>DataType *XDataType被推导为intdouble ,而X是不是容器的指针。
  2. With template<struct DataType, size_t N> and DataType (&X)[N] , DataType is deduced as int and double , and X is an array which can be used with range-based for loop. 使用template<struct DataType, size_t N>DataType (&X)[N]DataType被推导为intdouble ,而X是一个可以与基于范围的for循环一起使用的数组。
  3. With template<struct DataType> and DataType&& X or DataType const& X , DataType is deduced as int[7] or double[5] , and X is an array as well. 使用template<struct DataType>DataType&& XDataType const& XDataType被推导为int[7]double[5]X也是一个数组。

The problem is that you're passing the name of the array (eg, nArray ), which is just a pointer to the first element, basically. 问题是你传递的是数组的名称(例如, nArray ),它只是一个指向第一个元素的指针。 However, new-style for loops expect something on which you can call begin and end - a range. 但是,新式for循环期望您可以调用beginend - 一个范围。

The following changes make it work by using a vector instead of an array. 以下更改使其可以使用vector而不是数组。 Note that there are very few differences otherwise, and, in general, very few reason to use C-style arrays in contemporary C++. 请注意,除此之外几乎没有什么区别,并且通常很少有理由在当代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;

You have some problems: 你有一些问题:

1) DataType must be a container. 1)DataType必须是容器。 So, try to use: 所以,尝试使用:

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) You are not going to change the container. 2)你不会改变容器。 It's better to pass container by const reference: 最好通过const引用传递容器:

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

3) Change the loop like this: 3)像这样改变循环:

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

Code example: 代码示例:

#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;
}

As Igor suggested, If at all you wish to use DataType * then you need to do something like this 正如Igor建议的那样,如果你想使用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;
}

Output 产量

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

Explanation: 说明:

If you see void PrintData(int* nArray); 如果你看到void PrintData(int* nArray); & void PrintData(int (&nArray)[7] ); void PrintData(int (&nArray)[7] ); are similar declarations, except that seconds one tells where array ends. 是类似的声明,除了秒一告诉数组结束的位置。

Template function 模板功能

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

is deduced as' 被推断为'

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

You could also write 你也可以写

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

    cout << endl;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM