[英]Supporting different versions of boost in .h/.cpp files
I have a header and .cpp file (call it Foo.h/.cpp) that is structured like this (leaving out several irrelevant details for simplicity): 我有一个标头和.cpp文件(称为Foo.h / .cpp),其结构如下(为简单起见,省略了一些无关的细节):
Foo.h foo.h中
#include <boost/bimap.hpp>
const std::string & ToHeader(const int msgID);
int ToMsgID(const std::string & msgHdr);
typedef boost::bimap<int, std::string> MsgIDBimap;
MsgIDBimap & GetMessageIDToStringMap();
Foo.cpp Foo.cpp中
#include "Foo.h"
#include <boost/assign/list_of.hpp>
static MsgIDBimap msgIDBimap = boost::assign::list_of<MsgIDBimap::relation>
((int)ROM_MSG, "")
... // a whole bunch of other entries
; // end static bimap initialization
const std::string & ToHeader(const int msgID)
{
MsgIDBimap::left_iterator foundIT = msgIDBimap.left.find(msgID);
if(foundIT != msgIDBimap.left.end()) // found
{
return foundIT->second;
}
throw std::string("MSG_ID_NOT_FOUND");
}
int ToMsgID(const std::string & msgHdr)
{
int msgID = (int)MSG_UNKNOWN; // unknown message header
MsgIDBimap::right_iterator foundIT = msgIDBimap.right.find(msgHdr);
if(foundIT != msgIDBimap.right.end()) // found
{
msgID = foundIT->second;
}
return msgID;
}
MsgIDBimap & GetMessageIdToStringMap()
{
return msgIDBimap;
}
The problem is that now I need to support an earlier version of boost that does not support bimap (sucks, I know ... but I have no choice). 问题在于,现在我需要支持一个不支持bimap的boost的早期版本(我知道,糟透了,但是我别无选择)。 So far, this is my solution:
到目前为止,这是我的解决方案:
Foo.h foo.h中
#include <boost/version.hpp>
#define BOOST_VER_MAJOR (BOOST_VERSION/100000) // ex.: 1 in 1_37_0
#define BOOST_VER_MINOR ((BOOST_VERSION/100) % 1000) // ex.: 37 in 1_37_0
#define BOOST_VER_PATCH (BOOST_VERSION % 100) // ex.: 0 in 1_37_0
/*************************************************************************************************/
#if ((BOOST_VER_MAJOR >= 1) && (BOOST_VER_MINOR >= 35)) // boost greater than or equal to 1.35 (bimap available)
#include <boost/bimap.hpp>
#endif
/*************************************************************************************************/
const std::string & ToHeader(const int msgID);
int ToMsgID(const std::string & msgHdr);
/*************************************************************************************************/
#if ((BOOST_VER_MAJOR >= 1) && (BOOST_VER_MINOR >= 35)) // boost greater than or equal to 1.35 (bimap available)
typedef boost::bimap<int, std::string> MsgIDBimap;
MsgIDBimap & GetMessageIdToStringMap();
#endif
/*************************************************************************************************/
Foo.cpp Foo.cpp中
#include "Foo.h"
#include <boost/assign/list_of.hpp>
#if ((BOOST_VER_MAJOR >= 1) && (BOOST_VER_MINOR >= 35)) // boost greater than or equal to 1.35 (bimap available)
static MsgIDBimap msgIDBimap = boost::assign::list_of<MsgIDBimap::relation>
((int)ROM_MSG, "") // <ROM message> (no header)
; // end static msgIDBimap initialization
const std::string & ToHeader(const int msgID)
{
MsgIDBimap::left_iterator foundIT = msgIDBimap.left.find(msgID);
if(foundIT != msgIDBimap.left.end()) // found
{
return foundIT->second;
}
throw std::string("MSG_ID_NOT_FOUND");
}
int ToMsgID(const std::string & msgHdr)
{
int msgID = (int)MSG_UNKNOWN; // unknown message header
MsgIDBimap::right_iterator foundIT = msgIDBimap.right.find(msgHdr);
if(foundIT != msgIDBimap.right.end()) // found
{
msgID = foundIT->second;
}
return msgID;
}
MsgIDBimap & GetMessageIdToStringMap()
{
return msgIDBimap;
}
/*************************************************************************************************/
#else // boost less than 1.35, bimap not available
typedef std::map<int, std::string> MsgIDToStringMap;
static MsgIDToStringMap msgIDToStringMap = boost::assign::map_list_of<int, std::string>
((int)ROM_MSG, "") // <ROM message> (no header)
; // end static msgIDToStringMap initialization
const std::string & ToHeader(const int msgID)
{
const MsgIDToStringMap::const_iterator foundIT = msgIDToStringMap.find(msgID);
if(foundIT != msgIDToStringMap.end()) // found
{
return foundIT->second;
}
throw std::string("MSG_ID_NOT_FOUND");
}
#define FLIP_ARGS(x,y) (y,x)
typedef std::map<std::string, int> StringToMsgIDMap;
static StringToMsgIDMap stringToMsgIDMap = boost::assign::map_list_of<std::string, int>
FLIP_ARGS((int)ROM_MSG, "") // <ROM message> (no header)
; // end static stringToMsgIDMap initialization
int ToMsgID(const std::string & msgHdr)
{
int msgID = (int)MSG_UNKNOWN; // unknown message header
const StringToMsgIDMap::const_iterator foundIT = stringToMsgIDMap.find(msgHdr);
if(foundIT != stringToMsgIDMap.end()) // found
{
msgID = foundIT->second;
}
return msgID;
}
#endif
While this works, the problem is that the GetMessageIDToStringMap() function declaration/definition only exists in the later boost version scenario (the two scenarios are not 100% congruent to each other). 在此可行的同时,问题在于GetMessageIDToStringMap()函数的声明/定义仅存在于更高的增强版本方案中(这两种方案彼此之间并非100%一致)。 I know that the GetMessageIDToStringMap() function itself will not ever be needed for the earlier boost version scenario.
我知道,早期的增强版本方案将永远不需要GetMessageIDToStringMap()函数本身。
Ideally, I would like to leave the static bimap inside the .cpp file and move the GetMessageIDToStringMap() to another file somewhere so that Foo.h/.cpp are 100% congruent for each #ifdef block. 理想情况下,我想将静态bimap保留在.cpp文件中,并将GetMessageIDToStringMap()移至另一个文件中的某个位置,以便每个#ifdef块的Foo.h / .cpp都是100%一致的。 The issue is that the bimap is a static variable inside a .cpp file and no other file can access it.
问题是bimap是.cpp文件中的静态变量,其他文件无法访问它。 Even if I make the bimap a global variable instead of a static variable, I now have to expose a global variable in the header file which again would only exist in the later versions of boost.
即使我将bimap设置为全局变量而不是静态变量,我现在也必须在头文件中公开全局变量,而该全局变量将再次存在于boost的更高版本中。
Is there a way to resolve this so that the two versions of the file (boost >= 1.35 vs. earlier boost) are always 100% congruent to each other and yet the GetMessageIDToStringMap() function is available in another file? 有没有一种方法可以解决这个问题,以便文件的两个版本(boost> = 1.35与早期的boost)始终保持100%一致,而GetMessageIDToStringMap()函数在另一个文件中可用?
In response to the comment in the question: 针对问题的评论:
in foo.cpp: 在foo.cpp中:
typedef std::map<int, std::string> MsgIDToStringMap;
//you can remove the static
MsgIDToStringMap msgIDToStringMap = ...
Now in the other.cpp file: 现在在other.cpp文件中:
extern MsgIDToStringMap msgIDToStringMap;
//and you can use the global variable.
But as I said in the 1st comment I would prefer a singleton class. 但是,正如我在第一条评论中所说,我更喜欢单例课程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.