【问题标题】:whats wrong with my template overloaded << operator?我的模板重载 << 运算符有什么问题?
【发布时间】:2014-02-07 22:29:23
【问题描述】:

我必须为类分配实现一个名为Stack 的模板类。 Stack 有一个重载的流插入操作符。 以下是 Stack.h 文件的相关摘录:

...
#include <iostream>
using namespace std;

template<class T>
ostream& operator<<(ostream&,Stack<T>&);

template<class T>
class Stack
{
    public:
        friend ostream& operator<< <T>(ostream&,Stack<T>&);
        ...             
};

#include "Stack.cpp"
...

我无法更改 Stack.h,因为它是按原样提供的。 Stack.cpp 的相关摘录是:

template <class T>
ostream& operator<< (ostream& out, Stack<T>& stack)
{
    Stack<T>::Node* current = stack.top;

    out << "[";

    while (current)
    {
        out << current->element;
        current = current->next;
        if (current)
            out << ",";
    }

    out << "]";

    return out;
}
...

这在 Visual Studio 中编译和工作正常,但是,当使用 g++ 编译时,它会给出以下错误:

Stack.cpp:4: syntax error before '&'
Stack.cpp:4: 'ostream' was not declared in this scope
Stack.cpp:4: 'out' was not declare din this scope
Stack.cpp:4: 'Stack' was not declared in this scope
Stack.cpp:4: 'T' was not declared in this scope
Stack.cpp:4: 'stack' was not declared in this scope
Stack.cpp:5: declaration of 'operator <<' as non-function

这是为什么呢?有什么办法可以解决?

编辑:我补充说我已经包含了 iostream 并提供了命名空间。

【问题讨论】:

  • #include &lt;iostream&gt;, #include "Stack.h"?
  • 还有typename Stack&lt;T&gt;::Node* current = ...
  • Node 是一个在 Stack 内部定义的类。
  • 你需要typename
  • 可能是您正在尝试编译Stack.cpp

标签: c++ templates operator-overloading


【解决方案1】:

您不能在operator&lt;&lt; 声明中引用未声明的Stack&lt;T&gt;。您需要在 Stack.h 的顶部或在包含它的每个文件中包含 Stack.h 之前的前向声明 template&lt;class T&gt; Stack;

【讨论】:

    【解决方案2】:

    你应该请求你的教授允许对头文件进行一些更改,如下所示:

    #include <iostream>
    //using namespace std; is a VERY bad idea in header files, since it infects the entire program
    
    template<class T>
    class Stack; // Casey's fix
    
    // need to qualify ostream since using namespace std; went away
    template<class T>
    std::ostream& operator<<(std::ostream&,Stack<T>&);
    
    template<class T>
    class Stack
    {
        public:
            friend std::ostream& operator<< <T>(std::ostream&,Stack<T>&);
            ...             
    };
    
    // The .cpp extension by convention is used only for source files, not for inclusion targets.
    // Pick a different extension for template implementations, which get passed to #include
    #include "Stack.impl"
    

    如果你的教授没有看到这些变化的价值,留在他的课堂上会因为你会养成的所有坏习惯而变得相当消极,你应该开始考虑学习 C++ 的其他选择。

    【讨论】:

      【解决方案3】:

      问题是我试图单独编译 Stack.cpp。解决方案是,只编译使用模板类的文件,在本例中为 main.cpp

      我的错误生成文件如下所示:

      main: main.o Stack.o
          g++ -static main.o Stack.o -o main
      
      main.o: main.cpp
          g++ -c main.cpp
      
      Stack.o: Stack.cpp Stack.h
          g++ -c Stack.cpp
      

      正确的makefile是

      main: main.o
          g++ -static main.o -o main
      
      main.o: main.cpp Stack.cpp Stack.h
          g++ -c main.cpp
      

      感谢 juanchopanza 指出这一点。

      【讨论】:

      • Stack.o: Stack.cpp 的规则实际上是在 make 系统中使用模式预定义的。这就是为什么不应该将头文件命名为.cpp
      猜你喜欢
      • 1970-01-01
      • 2011-06-11
      • 1970-01-01
      • 2012-05-09
      • 2015-01-18
      • 1970-01-01
      • 2011-04-22
      • 2015-09-15
      • 1970-01-01
      相关资源
      最近更新 更多