包含<iosfwd>似乎会导致名称空间问题?</iosfwd>

时间:2012-05-12 16:39:07

标签: c++ templates

我试图理解为什么包含iosfwd会导致包括标准字符串在内的输出流不起作用。

// hc_list.h file
#ifndef HC_LIST_H
#define HC_LIST_H

#include <cstdlib>
#include <iosfwd> // including this file makes the output operator throw errors
#include <list>

template <typename T>
class hcList
{
    private:
    std::list<T> selfList ; // a single internal STL list to hold the values

    public:
    hcList(void) {} ;
    ~hcList(void){} ;
    template <typename U> friend std::ostream& operator<<(std::ostream &, const hcList<U> &) ;
} ;

template <typename U>
std::ostream& operator<<(std::ostream &out, const hcList<U> &outList)
{
    out << "test" << std::endl ; // this line throws two errors, stated below
    return out ;
}
#endif // HC_LIST_H

此代码包含在main.cpp文件中,其中主要功能如下:

// main.cpp file
#include <iostream>
#include "hc_list.h"
int main()
{
    std::cout << "Begin Test" << std::endl;
    return 0;
}

为了实际利用此代码并生成错误,需要一个包含列表头文件的空cpp文件。

// anyNamedFile.cpp file
#include "hc_list.h"

当我尝试编译时,收到以下错误:

error: no match for 'operator<<' in 'out<< "test"'
error: 'endl' is not a part of 'std'

是什么导致std命名空间搞砸了,不再允许我输出字符串?

1 个答案:

答案 0 :(得分:2)

这里有两个问题。第一个问题是您使用的是std::endl,但这是<ostream>中定义的,不包括在内。

第二个问题是你只包含标题<iosfwd>,它向前声明许多iostream类型。前向声明允许编译器知道类型存在。但是,您尝试使用这些类型的功能。由于您这样做,因此应该包含<ostream>,而不是<iosfwd><ostream>包含std::endl,因此应该处理所有事情。