C++不允许我将结构体用作模板参数。

4
也许这是某种标题问题……但是发生了什么:
编译器在以下行中报错:
Queue<Email> mailbox;

这是错误信息:

..\EmailSystem.h:25: error: ISO C++ forbids declaration of `Queue' with no type
..\EmailSystem.h:25: error: expected `;' before '<' token

Queue.h:

#ifndef QUEUE_H_
#define QUEUE_H_

#include <string>
#include "EmailSystem.h"

...

template <class B>
class Queue {
 ...
};

#endif /* QUEUE_H_ */

Queue.cpp:

#include "Queue.h"

...

template class Queue<Email>;

EmailSystem.h:

#ifndef EMAILSYSTEM_H_
#define EMAILSYSTEM_H_

#include <iostream>
#include <string>
#include <vector>
#include "Queue.h"

struct Email {
    ...
};

struct User {
    std::string name;
    Queue<Email> mailbox;
};

...

#endif /* EMAILSYSTEM_H_ */

2
还有,你避免使用std::dequestd::queue的特别原因吗? - Billy ONeal
出于教育目的,呵 - cactusbin
2个回答

11
你有一个循环包含。`Queue.h` 包含 `EmailSystem.h`,而 `EmailSystem.h` 又包含了 `Queue.h`,因此 include guards 可以确保头文件在第二次被包含时不会产生副作用。这意味着如果 `Queue.h` 是第一个被包含的头文件,则在它第一次被使用之前,`Queue` 将不会被声明,在 `EmailSystem.h` 中被包含,此时就会出现这种情况:
Queue<Email> mailbox;

我猜想,但我认为你的模板Queue(如果它真的是一个通用类模板)不需要了解Email,所以你应该从Queue.h中删除#include "EmailSystem.h"来解决你的问题。


谢谢。我将Email结构体移动到了一个单独的文件中并进行了包含。我需要包含Email结构体以便于“template class Queue<Email>”(就我所知)的使用。 - cactusbin
如果您需要显式实例化,则在该点上模板和模板参数都需要是完整的类型。 - CB Bailey

2

在声明class Queue之前,你需要在Queue.h中包含#include "EmailSystem.h"。这样当编译器试图创建struct User时,就会明白你尝试使用的Queue<Email>是什么。

请注意,EmailSystem.h和Queue.h互相包含。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接