gpt4 book ai didi

c++ - 语言环境构面构造函数被忽略

转载 作者:太空宇宙 更新时间:2023-11-04 13:31:31 25 4
gpt4 key购买 nike

locale Facet constructor :

Constructs a copy of other except for the facet of type Facet (typically deduced from the type of the argument) which is installed from the argument facet. If facet is NULL, the constructed locale is a full copy of other. The locale constructed in this manner has no name.

我尝试使用我的 Facet 进行构建here ,但是当我在我的 do_decimal_point 中放置一个断点时和 do_thousands_sep他们永远不会被称为:(

我可以看到 Facet被传入,但它被传递到标准库实现文件中,所以我看不到它是否做过任何事情。

我已经在 Visual Studio 2013、Clang 3.6.0 和 gcc 4.9.2 上试过了。 所有它们的行为就好像我从未通过过 Facet只是使用另一个 locale的行为。

我在任何编译器中都找不到针对此构造函数的任何错误。我认为我这样做是对的。为什么我不能得到 locale使用我的 Facet 构建?

编辑:

the request of 0x499602D2我添加了一个例子。有趣的是,Facet 确实似乎被拾起但没有get_money一起使用.我正在链接 live example of this (必须使用 locale("C") 而不是 locale("en-US") ):

class Foo : public std::moneypunct<char> {
protected:
char_type do_decimal_point() const {
cout << "Hit Foo::do_decimal_point";
return ',';
}
char_type do_thousands_sep() const {
cout << "Hit Foo::do_thousands_sep";
return '.';
}
};

int main()
{
cout.imbue(locale(locale("en-US"), new Foo));

const moneypunct<char>* temp = &use_facet<std::moneypunct<char>>(cout.getloc());

cout << temp->decimal_point() << endl << temp->thousands_sep() << endl;

istringstream USCurrency("1,234.56 -1,234.56 1.234,56 -1.234,56");
USCurrency.imbue(cout.getloc());

long double value;

USCurrency >> get_money(value, true);

return 0;
}

这个输出:

Hit Foo::do_thousands_sepHit Foo::do_decimal_point,
.

我希望它输出:

Hit Foo::do_thousands_sepHit Foo::do_decimal_point,
.
Hit Foo::do_thousands_sepHit Foo::do_decimal_point

编辑 2:

看来 moneypunct<char>无法继承,因为它没有正确构造,除非它是由 locale 内部构造的.这至少在 Visual Studio 上是个问题,因为它决定是否使用 thousands_sep通过 grouping .解决方法可能是完全重新实现 moneypunct<char>的功能。我现在正在修补它。与此同时,我还在此处添加了一个错误:https://connect.microsoft.com/VisualStudio/feedback/details/1524749/inheriting-from-moneypunct-requires-use-of-unavailable-construction-information

最佳答案

事实是,do_decimal_placedo_thousands_place 受到 get_money 的尊重。困难在于继承自的moneypunct是默认构造的,所以支持信息指示get_money调用do_decimal_place do_thousands_place 未设置。

moneypunct 的 Visual Studio 实现提供了两个公共(public)构造函数:

  1. moneypunct()
  2. moneypunct(const _Locinfo& _Lobj, size_t _Refs = 0, bool _Isdef = false)

locale 的构造函数调用第二个 moneypunct 构造函数。创建适当的 _Locinfo 是问题的关键,因为该信息似乎是特定于实现的。 linked 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()) {}
};

编辑:

这个解决方案是跨平台的,但也不能令人满意,因为所有必须添加到 punct_facet 的成员 已经存在 moneypunct .我不知道这种育肥的干净解决方法。此处提供了编译器特定的 hack:https://stackoverflow.com/a/31454039/2642059

如果 Visual Studio 将 v 表指针作为对象布局中的第一项,这将导致 punct_facet 看起来更像这样:

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 中不受支持,但在 gcc 5.1.0 中 受支持:http://coliru.stacked-crooked.com/a/e4a1d88b560d6d1b

关于c++ - 语言环境构面构造函数被忽略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31291004/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com