Предположим, что у меня есть следующий набор файлов:Correct опережающее объявление полностью специализированных шаблонов классов
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: Define полностью специализированные версия упомянутого класса шаблонов, упрощающая простоту использования.
#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' для переносимости. – erip
'typedef' не объявляет специализацию. –
Спасибо за подсказку. Моя компания использует только Visual Studio. Нет проблем с переносимостью. :-) – Aleph0