我是新手。我试图编写一个模板函数,从文本文件中获取字符串AND数值数据(例如,douubles),然后将其放入向量中。向量的每个元素都是不同的名称或数字。
上周我询问过载或模板是否最适合这种情况。我想使用模板方法,其中结果向量(我想要的)传递给函数以提供模板参数T.但是我遇到了问题。如果有人可以提供帮助,我将不胜感激!代码如下,然后是我得到的错误。
//我的代码:
template<typename T>
void readFile( const std::string& name, const std::string& find, std::vector<T>& results ){
std::ifstream file( name.c_str( ) );
std::string line;
while( std::getline( file, line ) )
{
if( line == find )
{
std::getline( file, line );
line.erase(remove( line.begin(), line.end(), '\'' ), line.end() );
std::istringstream streamLine( line );
results = std::vector<T>( std::istream_iterator<T>(streamLine), std::istream_iterator<T>() );
}
}
}
在main()中调用:
readFile( name, "label", results );
我得到的错误如下。我不明白函数调用如何与定义不匹配。对任何愚蠢的错误提前道歉!
error: no matching function for call to
'std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >,
std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >
::resize(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)'
奇怪的是,如果我让函数返回向量“result”而不是void,那么事情似乎有效。这就是我的意思:
std::vector<T> readFile( const std::string& name, const std::string& find, std::vector<T>& results )
在函数定义中使用return语句:
return std::vector<T>( std::istream_iterator<T>(streamLine), std::istream_iterator<T>() );
但这样做似乎很笨拙/糟糕。我原以为使用引用会更好。即使它不是更好,我很想知道为什么第一种方法(带有void)不起作用。
任何提示都将不胜感激!
答案 0 :(得分:1)
我不得不做一些工作来使这个完全可编辑的代码片段。以下是我提出的建议:
#include <string>
#include <vector>
#include <istream>
#include <fstream>
#include <iterator>
#include <sstream>
#include <algorithm>
template<typename T>
void readFile(const std::string& name,
const std::string& find,
std::vector<T>& results )
{
std::ifstream file( name.c_str( ) );
std::string line;
while( std::getline( file, line ) )
{
if( line == find )
{
std::getline( file, line );
line.erase(remove( line.begin(), line.end(), '\'' ), line.end() );
std::istringstream streamLine( line );
results = std::vector<T>( std::istream_iterator<T>(streamLine),
std::istream_iterator<T>() );
}
}
}
void do_it_with_strings(std::vector<std::string> &results)
{
readFile("fred", "barney", results);
}
此代码段与gcc 4.5.1编译得很好。 name
函数中results
和main
的确切类型是什么?此外,问题似乎是调用向量的resize
函数。您似乎没有在代码中直接执行此操作,尽管向量构造函数或赋值运算符可能在内部执行此操作。
但无论如何,我不建议你以这种方式编写代码。我建议你这样做:
#include <string>
#include <vector>
#include <istream>
#include <fstream>
#include <iterator>
#include <sstream>
#include <algorithm>
template<typename T>
std::vector<T> readFile(const std::string& name, const std::string& find )
{
std::ifstream file( name.c_str( ) );
std::string line;
while( std::getline( file, line ) )
{
if( line == find )
{
std::getline( file, line );
line.erase(remove( line.begin(), line.end(), '\'' ), line.end() );
std::istringstream streamLine( line );
return std::vector<T>( std::istream_iterator<T>(streamLine),
std::istream_iterator<T>() );
}
}
return std::vector<T>();
}
void do_it_with_strings(std::vector<std::string> &results)
{
results = readFile<std::string>("fred", "barney");
}
在这样的函数中,我认为最好是在调用函数时明确说明您期望读取的类型,而不是根据传入的vector
的类型隐式确定它。
答案 1 :(得分:1)
这是一段代码,可以从文件中获取字符串或数值:
#include <fstream>
#include <vector>
#include <iterator>
#include <algorithm>
template<typename T>
void read_values(const std::string& filename, std::vector<T>& coll)
{
std::fstream file(filename);
std::copy (std::istream_iterator<T>(file),
std::istream_iterator<T>(),
back_inserter(coll));
std::sort(coll.begin(), coll.end());
coll.erase(std::unique(coll.begin(), coll.end()), coll.end());
}
int main(int argc, char* argv[])
{
std::vector<int> values;
read_values("C:\\example.txt", values);
return 0;
}
如果你想改为读取字符串值,你只需要提供一个std :: vector std :: string来传递给模板函数。