事实上,do_decimal_place
and do_thousands_place
are受到尊重get_money
。困难在于事实上moneypunct
继承自默认构造,因此支持信息直接get_money
打电话do_decimal_place
and do_thousands_place
没有被设置。
Visual Studio 的实现moneypunct
提供了两个公共构造函数:
moneypunct()
moneypunct(const _Locinfo& _Lobj, size_t _Refs = 0, bool _Isdef = false)
locale
的构造函数调用第二个moneypunct
构造函数。创建一个合适的_Locinfo
是问题的关键,因为该信息似乎是特定于实现的。这链接的 Visual Studio Bug请求一种构造函数的方法moneypunct
无法访问实施细节。代替此信息的所有moneypunct
田地必须煮熟。
由于这个问题是关于延长预期工作moneypunct
最简单的方法是使用赋值运算符或复制构造函数。坏消息:两者都被删除。所以punct_facet(const money_punct&)
需要在内部编写实现复制构造函数的行为。需要复制的值对应于所有需要重写的虚函数punct_facet
。最后你的类将看起来类似于:
template <typename T>
class punct_facet : public T {
protected:
typename T::string_type m_grouping;
typename T::string_type m_curr_symbol;
typename T::string_type m_positive_sign;
typename T::string_type m_negative_sign;
int m_frac_digits;
typename T::pattern m_pos_format;
typename T::pattern m_neg_format;
typename T::char_type do_decimal_point() const {
return typename T::char_type(',');
}
typename T::char_type do_thousands_sep() const {
return typename T::char_type('.');
}
typename T::string_type do_grouping() const {
return m_grouping;
}
typename T::string_type do_curr_symbol() const {
return m_curr_symbol;
}
typename T::string_type do_positive_sign() const {
return m_positive_sign;
}
typename T::string_type do_negative_sign() const {
return m_negative_sign;
}
int do_frac_digits() const {
return m_frac_digits;
}
typename T::pattern do_pos_format() const {
return m_pos_format;
}
typename T::pattern do_neg_format() const {
return m_neg_format;
}
public:
punct_facet(const T& defaultFacet) : m_grouping(defaultFacet.grouping()),
m_curr_symbol(defaultFacet.curr_symbol()),
m_positive_sign(defaultFacet.positive_sign()),
m_negative_sign(defaultFacet.negative_sign()),
m_frac_digits(defaultFacet.frac_digits()),
m_pos_format(defaultFacet.pos_format()),
m_neg_format(defaultFacet.neg_format()) {}
};
EDIT:
这个解决方案是跨平台的,但它也不能令人满意,因为必须将所有成员添加到punct_facet
已经存在 in moneypunct
。我不知道有什么干净的解决方法可以解决这种问题。此处提供了特定于编译器的 hack:https://stackoverflow.com/a/31454039/2642059
这将导致punct_facet
鉴于 Visual Studio 将 v-table 指针放置为对象布局中的第一项,看起来更像是这样:
template <typename T>
class punct_facet : public T {
private:
void Init(const T* money){
const auto vTablePtrSize = sizeof(void*);
memcpy(reinterpret_cast<char*>(this) + vTablePtrSize, reinterpret_cast<const char*>(money) + vTablePtrSize, sizeof(T) - vTablePtrSize);
}
protected:
typename T::char_type do_decimal_point() const {
return typename T::char_type(',');
}
typename T::char_type do_thousands_sep() const {
return typename T::char_type('.');
}
public:
punct_facet(){
Init(&use_facet<T>(cout.getloc()));
}
punct_facet(const T* money){
Init(money);
}
};
顺便说一句,这个实现punct_facet
Clang 3.6.0 不支持,但是isgcc 5.1.0 支持:http://coliru.stacked-crooked.com/a/e4a1d88b560d6d1b