【发布时间】:2016-11-09 17:51:17
【问题描述】:
假设我有以下一堆文件:
Generic.h:复杂的模板类
#pragma once
template<typename K, typename V, template<typename Key, typename Value, typename ...> typename C>
struct GenericMap
{
C<K, V> key;
};
Special.h:定义提到的模板类的完全专用版本,简化易用性。
#pragma once
#include "Generic.h"
#include <string>
#include <map>
typedef GenericMap<std::string, int, std::map> SpecialMap;
Client.h:使用SpecialMap并定义前向声明的客户端。
#pragma once
class SpecialMap; // Wrong forward declaration
struct Client {
Client();
SpecialMap* map;
};
Client.cpp:客户端代码可能知道Generic.h和Special.h
#include "Client.h"
#include "Special.h"
Client::Client()
{
map["343"] = 2;
}
main.cpp:
#include <Client.h>
int main(int argc, char**args) {
Client c;
return 0;
}
GenericMap 表示没有前向声明的模板类。对于某些用户来说,SpecialMap 或 GenericMap 的完全专用版本就足够了,为了便于使用,使用了 typedef。
现在Client 在内部使用SpecialMap,但头文件应该只声明SpecialMap 的前向声明。
很遗憾,以下文件将无法编译。不知何故,张贴的前向声明就足够了。什么是正确的?
对于冗长的列表,我很抱歉,但这是我能想到的最小的无效示例。
【问题讨论】:
-
顺便说一句:我不推荐
#pragma once。使用#ifndef... #define... #endif模式实现可移植性。 -
A
typedef没有声明特化。 -
感谢您的提示。我的公司只使用 Visual Studio。不存在便携性问题。 :-)
-
@erip,你知道不支持
#pragma once的编译器吗? -
@Aleph0 使用 #pragma once 应该适用于任何现代编译器。不应该吗?
标签: c++ templates forward-declaration class-template