C++模板包含std::vector
C++ templates containing std::vector
最近我写了一个类,其中包含四个函数,用于打开和读取多列数据文件(最多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();
}
相关文章:
- 尝试使用 std::vector<std::thread时出现静态断言失败错误>
- 字符串化递归的"std::vector<std::vector<...>>"而不使用部分模板函数专用化
- 连接和压缩标准::vector<std::字符串的最佳方法>
- C++从 std::vector<std::function<中删除 std::function>>
- 如何在构造函数初始值设定项列表中使用 n 个元素初始化 std::vector<std::time_t>
- 如何使用 CUDA 将 std::vector<std::string> 复制到 GPU 设备
- 编译错误 std::vector<std::shared_ptr<T>>迭代器和擦除方法
- 将 std::vector<std::unique_ptr<T>> 移动到 std::vector<std::shared_ptr<T>>
- 如何从 boost::container::vector<std::string>::iterator 访问索引和对象?
- 使用 std::vector<std::future<int>> 和 std::async 启动几个线程时中止
- 为什么转置这个 std::vector<std::vector<std::string> > 这么慢?
- 是否有可能在没有复制的情况下传递 std::vector<int> 作为参数来获得 std::vector<std::array<int, 3>>?
- 在 boost::<double>asio::buffer 中使用像 std::vector<std::complex> 这样的参数
- 如何从 std::initializer_list<char const* 构建 std::vector<std::string>>
- 如何检查 std::vector<std::string> 的元素是否以某个子字符串开头?
- 在 std::vector<std::vector 中重新存储内部向量<TYPE>>
- 将 std::vector<std::string> 转换为 const char* const*
- 不能将结构push_back() 转换为 std::vector<std::shared_ptr<theStruct>> theVector
- SWIG:传递一个 std::vector< std::vector <double> >指向 python 的指针
- 将 std::vector<std::p air<const K, V>*> 转换为 std::vector<std::p air<const K, V>&g