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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3879162/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 13:57:15  来源:igfitidea点击:

How to forward declare a template class in namespace std?

c++templatesg++

提问by nakiya

#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

and used that function in my main. I get errors. Of course, I know that there are more template params for std::list(allocator I think). But, that is beside the point. Do I have to know the full template declaration of a template class to be able to forward declare it?

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

EDIT: I wasn't using a pointer before - it was a reference. I'll try it out with the pointer.

编辑:我之前没有使用指针 - 它是一个引用。我会用指针试一试。

回答by Jon Purdy

The problem is not that you can't forward-declare a template class. Yes, you do need to know all of the template parameters and their defaultsto be able to forward-declare it correctly:

问题不在于您不能向前声明模板类。是的,您确实需要知道所有模板参数及其默认值才能正确地向前声明它:

namespace std {
  template<class T, class Allocator = std::allocator<T>>
  class list;
}

But to make even such a forward declaration in namespace stdis explicitly prohibited by the standard: the onlything you're allowed to put in stdis a template specialisation, commonly std::lesson a user-defined type. Someone else can cite the relevant text if necessary.

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

Just #include <list>and don't worry about it.

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

Oh, incidentally, any name containing double-underscores is reserved for use by the implementation, so you should use something like TEST_Hinstead of __TEST__. It's not going to generate a warning or an error, but if your program has a clash with an implementation-defined identifier, then it's not guaranteed to compile or run correctly: it's ill-formed. Also prohibited are names beginning with an underscore followed by a capital letter, among others. In general, don't start things with underscores unless you know what magic you're dealing with.

哦,顺便说一句,任何包含双下划线的名称都保留供实现使用,因此您应该使用类似的名称TEST_H而不是__TEST__. 它不会生成警告或错误,但如果您的程序与实现定义的标识符发生冲突,则不能保证它可以正确编译或运行:它是格式错误的。还禁止以下划线开头的名称,后跟大写字母等。通常,除非您知道要处理的魔术,否则不要以下划线开头。

回答by user1638075

I solved that problem.

我解决了那个问题。

I was implementing an OSI Layer (slider window, Level 2) for a network simulation in C++ (Eclipse Juno). I had frames (template <class T>) and its states (state pattern, forward declaration).

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

The solution is as follows:

解决方法如下:

In the *.cppfile, you must include the Header file that you forward, i.e.

*.cpp文件中必须包含你转发的Header文件,即

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;

}

Its cpp:

它的 cpp:

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

template <class T>
bool State<T>::replace(Frame<T> *f){

And... another class.

还有……另一堂课。

回答by Grozz

Forward declaration should have complete template arguments list specified.

前向声明应指定完整的模板参数列表。

回答by Arne

there is a limited alternative you can use

您可以使用的替代方案有限

header:

标题:

class std_int_vector;

class A{
    std_int_vector* vector;
public:
    A();
    virtual ~A();
};

cpp:

cp:

#include "header.h"
#include <vector>
class std_int_vector: public std::vectror<int> {}

A::A() : vector(new std_int_vector()) {}
[...]

not tested in real programs, so expect it to be non-perfect.

没有在实际程序中测试过,所以期望它是不完美的。