【问题标题】:C++print containerC++打印容器
【发布时间】:2012-04-27 04:36:19
【问题描述】:

我正在尝试打印容器,例如集合和地图。我正在使用的书说以下代码是有效的:

#include <iostream>
#include <set>
#include <iterator>
#include <fstream>
using namespace std;

template <typename Container>
void print (const Container & c, ostream & out = cout)
{
    typename Container::const_iterator itr;
    for( itr=c.begin(); itr!=c.end(); ++itr)
        out << *itr << " ";
    out << endl;
}

int main()
{
    ifstream fin("Test.txt");
    set<string> s(  istream_iterator<string>(fin),
                    istream_iterator<string>() );
    print( s );

    return 0;
}

但我从 Visual Studio 的编译器中收到错误消息。 我错过了什么?我知道它可能很简单,比如包含,但我不熟悉 STL 容器和 C++ 迭代器。

我已经有#include &lt;iterator&gt;

错误:

  • 'Container':必须是类或命名空间,后跟'::'
  • 'itr' : 未声明的标识符
  • “const_iterator”:不是“全局命名空间”的成员

还有一些我确信是第一个的结果。

编辑:

根据教科书,以下代码应该与我的主要代码相同。我无法让它工作,但它可能会有所帮助:

ifstream fin("Test.txt");
string x;
set<string> s;
while( fin >> x)
    s.insert(x);

编辑:

Visual Studio 构建输出:

------ Build started: Project: project, Configuration: Debug Win32 ------
Build started 4/15/2012 1:19:25 PM.
InitializeBuildStatus:

  Touching "Debug\project.unsuccessfulbuild".

ClCompile:

  Project4.cpp

c:\users\admin\documents\visual studio 2010\projects\project\project\project4.cpp(11): error C2825: 'Container': must be a class or namespace when followed by '::'

          c:\users\admin\documents\visual studio 2010\projects\project\project\project4.cpp(22) : see reference to function template instantiation 'void print<std::set<_Kty>
(std::istream_iterator<_Ty>,std::istream_iterator<_Ty> (__cdecl *)(void))>(Container (__cdecl &),std::ostream &)' being compiled

          with

          [

              _Kty=std::string,

              _Ty=std::string,

              Container=std::set<std::string> (std::istream_iterator<std::string>,std::istream_iterator<std::string> (__cdecl *)(void))

          ]

c:\users\admin\documents\visual studio 2010\projects\project\project\project4.cpp(11): error C2039: 'const_iterator' : is not a member of '`global namespace''

c:\users\admin\documents\visual studio 2010\projects\project\project\project4.cpp(11): error C2146: syntax error : missing ';' before identifier 'itr'

c:\users\admin\documents\visual studio 2010\projects\project\project\project4.cpp(11): error C2065: 'itr' : undeclared identifier

c:\users\admin\documents\visual studio 2010\projects\project\project\project4.cpp(12): error C2065: 'itr' : undeclared identifier

c:\users\admin\documents\visual studio 2010\projects\project\project\project4.cpp(12): error C2228: left of '.begin' must have class/struct/union

          type is 'std::set<_Kty> (__cdecl &)'

          with

          [

              _Kty=std::string

          ]

c:\users\admin\documents\visual studio 2010\projects\project\project\project4.cpp(12): error C2065: 'itr' : undeclared identifier

c:\users\admin\documents\visual studio 2010\projects\project\project\project4.cpp(12): error C2228: left of '.end' must have class/struct/union

          type is 'std::set<_Kty> (__cdecl &)'

          with

          [

              _Kty=std::string

          ]

c:\users\admin\documents\visual studio 2010\projects\project\project\project4.cpp(12): error C2065: 'itr' : undeclared identifier

c:\users\admin\documents\visual studio 2010\projects\project\project\project4.cpp(13): error C2065: 'itr' : undeclared identifier



Build FAILED.



Time Elapsed 00:00:01.00

========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

【问题讨论】:

  • 这个函数怎么调用?有什么论据?
  • 代码看起来不错。会不会是你没有用容器调用print函数?
  • 您的容器中是否包含 iostream 无法理解的内容?所以不是原始类型?
  • 似乎VS编译器有问题。 GCC 编译得很好。
  • VS 给你的错误信息是什么?

标签: c++ iterator containers


【解决方案1】:

它认为这是一个函数声明:

set<string> s(  istream_iterator<string>(fin),
                istream_iterator<string>() );

添加一对额外的括号将更正它:

set<string> s( (istream_iterator<string>(fin)),
                istream_iterator<string>() );

如果你搜索Most Vexing Parse,SO 上有很多这样的例子。

编辑:您还需要添加#include &lt;string&gt;

【讨论】:

  • 这与 Mat 中的代码具有相同的净效果:(请参阅下面的评论)。感谢您的尝试。从这里的回复来看,MSVS 似乎是为了吸引我,因为它适用于 GCC 中的其他所有人。
  • @AnthonyW:在我添加额外的括号后,您的示例代码在 MSVC++ 2010(警告级别/W4)上为我编译干净。
  • @AnthonyW:我刚刚注意到你还需要#include &lt;string&gt;
  • 我同时尖叫和哭泣。 #捂脸!!谢谢高炉!
  • @AnthonyW:如果 C++ 编译器提供更好的错误消息,那会有所帮助,不是吗?
【解决方案2】:

似乎编译器(也是 clang++)似乎感到困惑。不过,以下内容对我有用:

#include <iostream>                                                         
#include <set>                                                              
#include <iterator>                                                         
#include <fstream>                                                          

using namespace std;                                                        

template <typename Container>                                               
void print (const Container & c, ostream & out = cout)                      
{                                                                           
    typename Container::const_iterator itr;                                 
    for( itr=c.begin(); itr!=c.end(); ++itr)                                
        out << *itr << " ";                                                 
    out << endl;                                                            
}                                                                           

int main()                                                                  
{                                                                           
    ifstream fin("Test.txt");                                               
    istream_iterator<string> first(fin), last;                              
    set<string> s(first, last);                                             
    print(s);                                                               

    return 0;                                                               
}

但是,我建议将您的 print 函数转换为接受使用 std::copy 输出的迭代器范围的函数,如下所示:http://www.sgi.com/tech/stl/ostream_iterator.html

【讨论】:

  • 我只是准确地复制/粘贴了您的代码,但我仍然收到我在 Mat 的帖子和一大堆类似的帖子中引用的 binary'&gt;&gt;' 错误。这些都没有指向我程序本身的任何代码。
  • 对不起,您指的是什么?是使用编辑中的while 循环的main 函数吗?在这个线程中,没有 Mat 发布任何内容,他也没有在关于“最令人烦恼的解析”的线程中发布任何内容。
  • Mat 放弃后删除了他的帖子。我所指的错误的修复只是#include &lt;string&gt;。然而,这个错误是如此模糊,我永远都不会想到这就是问题所在。
  • 很高兴您发现了错误。我还发现 MSVC 错误消息几乎难以理解。您可能想尝试一下clang。这是我所知道的最符合标准的编译器,恕我直言,它会产生最好的错误消息(包括指向错误的颜色和箭头)。
  • 我可能不得不试一试;我一直在使用 Eclipse 编写 android 应用程序,它让我认为简单的事情是理所当然的,比如易于理解的错误消息和一键导入。如果 clang 具有相似的性质,我肯定很快就会成为粉丝。
猜你喜欢
  • 1970-01-01
  • 2017-04-26
  • 2014-05-17
  • 1970-01-01
  • 2016-03-07
  • 2017-07-30
  • 2021-03-17
  • 1970-01-01
  • 2019-02-16
相关资源
最近更新 更多