C++新手:模板函数问题 - 从文本文件中获取字符串和数字数据,将其放入向量中

发布于 2024-10-16 08:57:37 字数 1815 浏览 5 评论 0原文

我是新手。我尝试编写一个模板函数,从文本文件中获取字符串和数字数据(例如双精度数),然后将其放入向量中。向量的每个元素都是不同的名称或数字。

上周我问重载或模板是否最适合这个问题。我想使用模板方法,将结果向量(我想要的)传递给函数以提供模板参数 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> >&)'

奇怪的是,如果我让函数返回向量“结果”而不是 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)不起作用。

任何提示将不胜感激!

I am a newbie. I have tried to write a template function that gets string AND numerical data (for example, douubles) from a text file, then puts it in a vector. Each element of the vector is a different name or number.

Last week I asked whether overloading or a template might be best for this. I would like to go with a template method, where the results vector (what I want) is passed to the function to provide the template parameter T. But I'm having problems. If anyone could help, I would be grateful! The code is below, followed by the error I'm getting.

// My code:

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

Call in main():

readFile( name, "label", results );

The error I'm getting is below. I don't understand how the function call doesn't match the definition. Apologies in advance for any dumb mistakes!

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> >&)'

The weird thing is that if I make the function return the vector "result" instead of void, then things seem to work. Here's what I mean:

std::vector<T> readFile( const std::string& name, const std::string& find, std::vector<T>& results )

with a return statement in the function definition of:

return std::vector<T>( std::istream_iterator<T>(streamLine), std::istream_iterator<T>() );

But it seems clunky/bad style to do it this way. I would have thought that using references would be better. Even if it isn't better, I'm curious to know why the first method (with void) doesn't work.

Any tips would be appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

孤寂小茶 2024-10-23 08:57:37

我必须做大量工作才能使其成为完全可编译的代码片段。这是我的想法:

#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 中正常编译。 main 函数中 nameresults 的确切类型是什么?另外,问题似乎是调用向量的 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 的类型隐式确定它 你传入了。

I had to do a bunch of work to make this a fully compilable code snippet. Here is what I came up with:

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

This code snippet compiles just fine with gcc 4.5.1. What are the exact types of name and results in your main function? Also, the problem seems to be calling the vector's resize function. You don't appear to be doing that directly in your code, though it's possible the vector constructor or assignment operator does it internally.

But regardless, I wouldn't suggest you write your code that way anyway. I would suggest you do this instead:

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

In a function like this, I think it's better to be explicitly stating the type you're expecting to read when you call the function rather than have it implicitly determined from the type of the vector you pass in.

百合的盛世恋 2024-10-23 08:57:37

下面是一段代码,可以从文件中获取字符串或数值:

#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::string 的 std::vector 即可传递到模板函数中。

Here is a piece of code which will get you either strings or numerical values from a file:

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

If you wish to read string values instead, you just need to provide a std::vector of std::string to pass into the template function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文