C++模板包含std::vector

C++ templates containing std::vector

本文关键字:vector std 包含 C++      更新时间:2023-10-16

最近我写了一个类,其中包含四个函数,用于打开和读取多列数据文件(最多4列)。在函数中,要打开的文件名"file_name"从主程序传递给类"Read_Columnar_file"中的函数。使用std::vector读取数据并将其传递回主程序。然而,它要求程序员每次使用输入列时都要更改输入列的数据类型,这会导致错误。文件名将始终是一个字符串,因此不需要模板化;然而,使用vector读取的数组的数据类型可能会发生变化,因此需要对其进行通用模板化。我正在尝试将该类转换为模板类,但缺少对制作包含std::vector的模板的过程的一些基本理解。为了简化开发过程,我回到了类中一个名为"Read_One_Column"的例程,并试图将其转换为一个模板,其中数据类型标记为Type1。我认为我的问题在于语法,因为调试器告诉我主程序中的命令是未定义的。任何有助于纠正这一问题的建议都将不胜感激。现有代码的副本附在下面。

#include <vector>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <iterator>
template <class Type1> class Read_Columnar_File {
public:
    void Read_One_Column(const std::string& file_name,std::vector<Type1>& Column1);
};
template <class Type1> void Read_Columnar_File<Type1>::Read_One_Column(const std::string& file_name,
                                                                       std::vector<Type1>& Column1)
{
    std::ifstream inp(file_name,std::ios::in | std::ios::binary);
    std::istream_iterator<Type1> start((inp)), end;
    if(inp.is_open()) {
    Column1.assign(start,end);
}
    else std::cout << "Cannot Open " << file_name << std::endl;
    inp.close();
}
int main(int argc, const char * argv[]) {
    int i;
    std::vector<float> str1;
    Read_Columnar_File<float> ob1;
    char str[20];
    std::strcpy(str,"Test.txt");
    ob1.Read_One_Column(str,str1);
    for(i=0; i < 7; i++) std::cout << str1[i] << std::endl;
    return 0;
}

语法更简单:

template <typename Type1>
void Read_One_Column(const std::string& file_name,
                     std::vector<Type1>& Column1) {
    ...
}

根本不需要创建类(它只是一个模板函数)。

如果由于其他原因需要将函数放入类中,则语法与相同

struct Read_Columnar_File {
    ...
    template<typename Type1>
    void Read_One_Column(const std::string& file_name,
                         std::vector<Type1>& Column1) {
        ...
    }
}

并且它将是该类的模板方法。

为了完全解决这个问题,我发布了最终的正确代码,因为我相信其他人将来也会有同样的问题,我希望这能帮助他们。为了回答我的问题,在编程模板时,整个算法需要包含在头中,并且不能在头和实现文件之间分割。该程序是从输入文件中读取列数据的一种非常通用的方法,并假设每列数据的长度与其他列相同。用户只需将头文件与主程序类似,即可指定矢量定义中每列的数据类型并读取数据。主程序如下所示。此版本允许用户调用4个不同的函数,这些函数可用于读取多达四列的数据。

    #include <vector>
    #include <iostream>
    #include <cstring>
    #include "Read_Columnar_File.h"
    int main(int argc, const char * argv[]) {
        char str[20];
        strcpy(str,"Test.txt");
        // - Format for reading in a single column of data
        //   Data in this case is declared as a float in
        //   the vector, but it can be any data type
        /*
        std::vector<float> str2;
        Read_One_Column(str,str2);
        */
        // - Format for reading in two columns of data from
        //   an input file
        /*
        std::vector<float> str2;
        std::vector<int> str3;
        Read_Two_Columns(str,str2,str3);
         */
        // - Format for reading in three columns of data from
        //   an input file
        /*
        std::vector<float> str2;
        std::vector<int> str3;
        std::vector<int> str4;
        Read_Three_Columns(str,str2,str3,str4);
         */
        std::vector<float> str2;
        std::vector<int> str3;
        std::vector<int> str4;
        std::vector<float> str5;
        Read_Four_Columns(str,str2,str3,str4,str5);
        return 0;
    }
The implementation file is shown below.
    #include <vector>
    #include <stdio.h>
    #include <fstream>
    #include <iterator>
    template <class X> void Read_One_Column(const std::string& file_name,std::vector<X>& Column1)
    {
        std::ifstream inp(file_name,std::ios::in | std::ios::binary);
        std::istream_iterator<X> start((inp)), end;
        if(inp.is_open()) {
            Column1.assign(start,end);
        }
        else std::cout << "Cannot Open " << file_name << std::endl;
        inp.close();
    }
    template <class X,class Y> void Read_Two_Columns(const std::string& file_name,std::vector<X>& Column1,
                                            std::vector<Y>& Column2)
    {
        int i;
        X Col1;
        Y Col2;
        std::ifstream inp(file_name,std::ios::in | std::ios::binary);
        if(inp.is_open()){
        for(i=0; i < 7; i++){
                inp >> Col1 >> Col2;
                Column1.push_back(Col1), Column2.push_back(Col2);
            }
        }
        else std::cout << "Cannot Open " << file_name << std::endl;
        inp.close();
     }
    template <class X,class Y, class Z> void Read_Three_Columns(const std::string& file_name,std::vector<X>& Column1,
                                                                std::vector<Y>&     Column2,std::vector<Z>& Column3
    {
        int i;
        X Col1;
        Y Col2;
        Z Col3;
        std::ifstream inp(file_name,std::ios::in | std::ios::binary);
    if(inp.is_open()){
        for(i=0; i < 7; i++){
            inp >> Col1 >> Col2 >> Col3;
            Column1.push_back(Col1), Column2.push_back(Col2), Column3.push_back(Col3);
        }
    }
    else std::cout << "Cannot Open " << file_name << std::endl;
    inp.close();
}
template <class X,class Y, class Z,class A> void Read_Four_Columns(const std::string& file_name,std::vector<X>& Column1,
                                                            std::vector<Y>& Column2,std::vector<Z>& Column3,
                                                            std::vector<A>& Column4)
{
    int i;
    X Col1;
    Y Col2;
    Z Col3;
    A Col4;
    std::ifstream inp(file_name,std::ios::in | std::ios::binary);
    if(inp.is_open()){
        for(i=0; i < 7; i++){
            inp >> Col1 >> Col2 >> Col3 >> Col4;
            Column1.push_back(Col1), Column2.push_back(Col2),
            Column3.push_back(Col3), Column4.push_back(Col4);
        }
    }
    else std::cout << "Cannot Open " << file_name << std::endl;
    inp.close();
}
相关文章: