如何转发在命名空间std中声明模板类?

nak*_*iya 129 c++ templates g++

#ifndef __TEST__
#define __TEST__

namespace std
{
    template<typename T>
    class list;
}

template<typename T>
void Pop(std::list<T> * l)
{
    while(!l->empty())
        l->pop();
}

#endif
Run Code Online (Sandbox Code Playgroud)

并在我的主要使用该功能.我收到错误.当然,我知道有更多的模板参数std::list(我认为是分配器).但是,这是不重要的.我是否必须知道模板类的完整模板声明才能转发声明它?

编辑:我之前没有使用指针 - 这是一个参考.我会用指针试一试.

Jon*_*rdy 141

问题不在于您无法转发声明模板类.是的,您需要知道所有模板参数及其默认值才能正确地正确声明它:

namespace std {
  template<class T, class Allocator = std::allocator<T>>
  class list;
}
Run Code Online (Sandbox Code Playgroud)

但是,为了使在连这样一个向前声明namespace std由该标准明确禁止:在只有你允许把在事情std是一个模板专业化,通常std::less在用户定义类型.如有必要,其他人可以引用相关文本.

只是#include <list>不要担心.

哦,顺便说一句,任何包含双下划线的名称都保留供实现使用,所以你应该使用类似的东西TEST_H代替__TEST__.它不会生成警告或错误,但如果您的程序与实现定义的标识符发生冲突,则无法保证编译或运行正确:它的格式不正确.同样禁止的名称以下划线开头,后跟大写字母等.一般情况下,除非你知道你正在处理什么魔法,否则不要用下划线开始.

  • @Mark:因为它是`#pragma`,这就是原因.虽然这是一个选择. (11认同)
  • Jon/Nakiya,为什么不使用`#pragma once`而不是#ifdef.如今,它得到了大多数编译器的支持. (7认同)
  • 为什么禁止在`namespace std` btw中转发声明内容? (4认同)
  • 看看这个答案(http://stackoverflow.com/questions/307343/forward-declare-an-stl-container/307408#307408)和链接的新闻组讨论. (4认同)
  • 这个问题有很多重复的内容.只需搜索:http://stackoverflow.com/search?q = pragma + once (2认同)

小智 20

我解决了这个问题.

我正在为C++(Eclipse Juno)中的网络模拟实现OSI层(滑块窗口,级别2).我有框架(模板<class T>)及其状态(状态模式,前向声明).

解决方案如下:

在该*.cpp文件中,您必须包含您转发的头文件,即

ifndef STATE_H_
#define STATE_H_
#include <stdlib.h>
#include "Frame.h"

template <class T>
class LinkFrame;

using namespace std;

template <class T>
class State {

  protected:
    LinkFrame<int> *myFrame;

}
Run Code Online (Sandbox Code Playgroud)

它的cpp:

#include "State.h"
#include "Frame.h"
#include  "LinkFrame.h"

template <class T>
bool State<T>::replace(Frame<T> *f){
Run Code Online (Sandbox Code Playgroud)

还有......另一堂课.

  • 在头文件中放置任何`using namespace`是一种非常糟糕的做法,因为它可以防止使用该头文件的任何人使用本来有效的本地名称.它基本上打败了命名空间的整个点. (33认同)

Gro*_*ozz 10

前向声明应该具有指定的完整模板参数列表.