通过Mex开展一个关于C ++和Matlab合作的大型项目,我们正在与我们的一个单身人士进行斗争。
该类是在预处理期间通过宏生成的,所以看起来有点奇怪。
class AdditionalOperation {
private:
const std::string* val;
typedef std::map<std::string, const std::string*> StringMap;
static StringMap& getStringToPointerMap()
{
static StringMap map;
return map;
}
static boost::mutex& getMutex()
{
static boost::mutex mutex;
return mutex;
}
AdditionalOperation(const std::string* s)
:val(s)
{}
private:
static std::string* none_string()
{
static std::string s = "none";
static int count = 0;
boost::mutex::scoped_lock lock(getMutex());
if(count++ == 0) {
getStringToPointerMap().insert(std::make_pair(s,&s));
}
return &s;
}
public:
static AdditionalOperation none()
{
return AdditionalOperation(none_string());
}
private:
static std::string* norm_string()
{
static std::string s = "norm";
static int count = 0;
boost::mutex::scoped_lock lock(getMutex());
if(count++ == 0) {
getStringToPointerMap().insert(std::make_pair(s,&s));
}
return &s;
}
public:
static AdditionalOperation norm()
{
return AdditionalOperation(norm_string());
}
private:
static void prepare()
{
none();
norm();
}
public:
static AdditionalOperation fromString(std::string s)
{
static int count = 0;
if(count++ == 0)
prepare();
boost::mutex::scoped_lock lock(getMutex());
StringMap& map = getStringToPointerMap();
StringMap::iterator location = map.find(s);
if(location == map.end()) {
throw UnknownEnumValue(s);
}
return AdditionalOperation(location->second);
}
std::string toString() const
{
return *val;
}
bool operator==(const AdditionalOperation& other) const
{
return val == other.val;
}
bool operator!=(const AdditionalOperation& other) const
{
return !(*this == other);
}
};
所有这些代码都是从这一行生成的(通过如上所述的宏):
DECLARE_SENUM(AdditionalOperation, none, norm);
这是一个很好的界面,我们希望继续使用。
我们希望使用此类作为枚举的替代,因为我们需要将它们从字符串转换为字符串。在这个类中,我们有2个'枚举'成员,即norm和none。
现在我们已经添加了一些日志记录并确定了none_string和norm_string函数内的insert操作被调用了两次,即使我们的计数器应该阻止它。
我们尝试过的一些事情:
我们认为,由于动态库,可能会声明并激活此类的多个实例。但我们也使用其他没有出现任何问题迹象的单身人士。
我希望它足够清楚,可以随时提供额外的信息或澄清!
提前致谢!
答案 0 :(得分:1)
显然,你的问题太复杂了。
std::string const& to_string(MyEnum e) {
static std::string const First = "First";
static std::string const Second = "Second";
switch(e) {
case MyEnum::First: return First;
case MyEnum::Second: return Second;
}
throw std::runtime_error("Unknown enum value");
}
如果不是更好更快,也会起作用。