c++ - locale Facet Constructor Ignored -


the locale facet constructor:

constructs copy of other except facet of type facet (typically deduced type of argument) installed argument facet. if facet null, constructed locale full copy of other. locale constructed in manner has no name.

i try construct using facet here, when put break-point in do_decimal_point , do_thousands_sep never called :(

i can see facet being passed in, it's passed standard library implementation files can't see if ever done it.

i've tried on visual studio 2013, clang 3.6.0, , gcc 4.9.2. all of them behave though had never passed in facet using other locale's behavior.

i can't find bugs against constructor in of compilers. think i'm doing right way. why can't locale construct using facet?

edit:

at the request of 0x499602d2 have added example. it's interesting note facet does seem picked not used get_money. i'm linking live example of this (which useslocale("c") instead of 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; } 

this outputs:

hit foo::do_thousands_sephit foo::do_decimal_point,
.

i expect output:

hit foo::do_thousands_sephit foo::do_decimal_point,
.
hit foo::do_thousands_sephit foo::do_decimal_point

edit2:

it appears moneypunct<char> can't inherited doesn't constructed properly, unless constructed internally locale. @ least on visual studio problem because determines whether use thousands_sep grouping. work around may reimplement moneypunct<char>'s functionality. i'm tinkering now. in meantime i've added bug here: https://connect.microsoft.com/visualstudio/feedback/details/1524749/inheriting-from-moneypunct-requires-use-of-unavailable-construction-information

the fact is, do_decimal_place , do_thousands_place are respected get_money. difficulty in fact moneypunct being inherited being default constructed, supporting information direct get_money call do_decimal_place , do_thousands_place not being set up.

visual studio's implementation of moneypunct provides 2 public constructors:

  1. moneypunct()
  2. moneypunct(const _locinfo& _lobj, size_t _refs = 0, bool _isdef = false)

locale's constructor calls 2nd moneypunct constructor. creating proper _locinfo crux of problem information seems implementation specific. linked visual studio bug requests way construct functional moneypunct without access implementation details. in lieu of information moneypunct fields must cooked up.

since question extending expected working moneypunct easiest way use assignment operator or copy constructor. bad news: both of deleted. punct_facet(const money_punct&) need written internally implementing behavior of copy constructor. values need copied correspond virtual functions need overridden , punct_facet. in end class end looking similar this:

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:

this solution cross platform unsatisfactory, because members had added punct_facet already exist in moneypunct. not aware of clean workaround fattening. compiler specific hack available here: https://stackoverflow.com/a/31454039/2642059

this result in punct_facet looked more given visual studio places v-table pointer first item in object layout:

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);     } }; 

incidentally implementation of punct_facet not supported in clang 3.6.0 is supported in gcc 5.1.0: http://coliru.stacked-crooked.com/a/e4a1d88b560d6d1b


Comments

Popular posts from this blog

toolbar - How to add link to user registration inside toobar in admin joomla 3 custom component -

linux - disk space limitation when creating war file -