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

时间:2016-01-22 06:03:13

标签: c++ c++11

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

代码如下所示:

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中收到变量Data is unclared 的错误。

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

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

4 个答案:

答案 0 :(得分:4)

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

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

    #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是一个可以与之一起使用的数组基于范围的循环。
    3. 使用template<struct DataType>DataType&& XDataType const& XDataType推断为int[7]double[5],而X是阵列也是如此。

答案 1 :(得分:2)

问题在于你传递的是数组的名称(例如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;

答案 2 :(得分:1)

你有一些问题:

1)DataType必须是容器。所以,尝试使用:

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)你不会改变容器。最好通过const引用传递容器:

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

答案 3 :(得分:1)

正如伊戈尔所说,如果你想使用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);&amp; void PrintData(int (&nArray)[7] ); 是类似的声明,除了秒数告诉数组结束的位置。

模板功能

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

推断为&#39;

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

你也可以写

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

    cout << endl;
}