[英]Why std::bad_cast exception in boost::locale::date_time for global but not local objects?
I'm having problems writing a wrapper class using the boost::locale::date_time library.我在使用 boost::locale::date_time 库编写包装器 class 时遇到问题。 Specifically, I cannot create a global object from my class, though everything works fine other than that.
具体来说,我无法从我的 class 创建全局 object,尽管除此之外一切正常。
Here's relevant sample code:这是相关的示例代码:
// DateTimeWrapper.h
#include <boost\\locale\\date_time.hpp>
#include <boost\\locale.hpp>
class DateTimeWrapper
{
public:
DateTimeWrapper();
~DateTimeWrapper();
// ... Other methods...
protected:
boost::locale::date_time* m_date_time;
static void Init_Global_Locale();
static bool m_Global_Locale_Initialized;
};
// DateTimeWrapper.cpp
bool DateTimeWrapper::m_Global_Locale_Initialized = false;
DateTimeWrapper::DateTimeWrapper()
{
Init_Global_Locale();
// The following line will work for the local object,
// but throws a std::bad_cast exception for the global object
m_date_time = new boost::locale::date_time;
}
DateTimeWrapper::~DateTimeWrapper()
{
delete m_date_time;
}
void DateTimeWrapper::Init_Global_Locale()
{
if (!m_Global_Locale_Initialized)
{
boost::locale::generator gen;
std::locale l = gen("");
std::locale::global(l);
m_Global_Locale_Initialized = true;
}
}
// This object throws a std::bad_cast exception. Code runs normally if I comment out the following line.
DateTimeWrapper global_date_time_object;
int main()
{
// This object works just fine
DateTimeWrapper local_date_time_object;
// Do stuff with local_date_time_object...
return(0);
}
As you can see in the code, I use a static member to make sure the global locale is initialized the first time a DateTimeWrapper object is created.正如您在代码中看到的,我使用 static 成员来确保在第一次创建 DateTimeWrapper object 时初始化全局语言环境。 Normally, this prevents a std::bad_cast exception from being thrown when I create my boost::locale::date_time member.
通常,这可以防止在我创建 boost::locale::date_time 成员时引发 std::bad_cast 异常。 However, I still receive the exception from that line when the first DateTimeWrapper object created is a global instance.
但是,当创建的第一个 DateTimeWrapper object 是全局实例时,我仍然从该行收到异常。
Note that stepping through the debugger, I can confirm that all lines in the Init_Global_Locale() method are run during construction of the global object.请注意,通过调试器,我可以确认 Init_Global_Locale() 方法中的所有行都在构建全局 object 期间运行。 This sample code also declares DateTimeWrapper::m_Global_Locale_Initialized before it declares global_date_time_object, within the same source file, so I know that order-of-initialization is not the problem here (confirmed by stepping through with the debugger anyhow).
此示例代码还在同一源文件中声明 global_date_time_object 之前声明了 DateTimeWrapper::m_Global_Locale_Initialized,因此我知道这里的初始化顺序不是问题(无论如何通过调试器单步执行来确认)。
So why does the code work for local objects but not global objects, even though I can see all lines of code are run through, in the correct order, for both versions?那么为什么代码适用于本地对象而不适用于全局对象,即使我可以看到所有代码行都以正确的顺序运行,对于两个版本?
I cannot reproduce the error (with the code shown in a single TU).我无法重现错误(使用单个 TU 中显示的代码)。
My hunch is that you have void DateTimeWrapper::Init_Global_Locale()
and m_Global_Locale_Initialized
defined in another translation unit, which lands you in SIOF (static initialization order fiasco).我的预感是您在另一个翻译单元中定义了 void
DateTimeWrapper::Init_Global_Locale()
和m_Global_Locale_Initialized
,这使您陷入了SIOF (静态初始化顺序惨败)。
Besides, there are numerous complexities about your types inviting errors (using non-owned pointers, not following Rule-Of-Zero/Three/Five ).此外,您的类型引发错误有许多复杂性(使用非拥有指针,不遵循零/三/五规则)。 I'd write it much simpler, using C++11's function local static initialization:
我会写得更简单,使用 C++11 的 function 本地 static 初始化:
#include <boost/locale.hpp>
#include <boost/locale/date_time.hpp>
struct EnsureLocaleBase {
EnsureLocaleBase() { Init(); }
private:
static bool Init() {
static auto const s_init = [] {
boost::locale::generator gen;
std::locale l = gen("");
std::locale::global(l);
return true;
}();
return s_init;
}
};
class DateTimeWrapper : EnsureLocaleBase {
boost::locale::date_time m_date_time;
};
DateTimeWrapper global_date_time_object;
int main() {
DateTimeWrapper local_date_time_object;
}
Function local statics don't suffer SIOF and also are thread-safely initialized. Function 局部静态不会遭受 SIOF 并且也是线程安全初始化的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.