Проблема с командой System.out.printf в Java

Функции шаблона-помощника или перегруженные операторы (например, & lt; & amp;) могут использоваться для вызова селектора потоков - специализированного статического шаблона. Специалисты селектора потоков затем выбирают правильные функции потоковой передачи, основанные на сериализованном типе:

template 
boost::archive::xml_iarchive&
stream(boost::archive::xml_iarchive& ia,
       const boost::serialization::nvp& nvp)
{
  return StreamSelector::stream(ia, nvp);
}

template 
boost::archive::xml_oarchive&
stream(boost::archive::xml_oarchive& oa,
       const boost::serialization::nvp& nvp)
{
  return StreamSelector::stream(oa, nvp);
}

Стандартный класс статического шаблона селектора потоков может быть определен для любого типа, поддерживаемого boost::archive::xml_iarchive, следующим образом:

template 
class StreamSelector {
 public:
  static boost::archive::xml_iarchive&
  stream(boost::archive::xml_iarchive& ia,
         const boost::serialization::nvp& nvp)
  {
    ia.operator >>(nvp);
    return ia;
  }

  static boost::archive::xml_oarchive&
  stream(boost::archive::xml_oarchive& oa,
         const boost::serialization::nvp& nvp)
  {
    oa.operator <<(nvp);
    return oa;
  }
};

Тогда селектор потоков может быть специализирован для double для обработки NaN или для вывода значений с плавающей запятой в более удобочитаемом формате в архив:

template <>
class StreamSelector {
 public:
  constexpr static double nan = std::numeric_limits::quiet_NaN();
  constexpr static const char* nanCStr = "nan";

  static boost::archive::xml_iarchive&
  stream(boost::archive::xml_iarchive& ia,
         const boost::serialization::nvp& nvp)
  {
    std::string iStr;
    ia >>  boost::serialization::make_nvp(nvp.name(), iStr);
    if(iStr == nanCStr) nvp.value() = nan;
    else nvp.value() = std::stod(iStr);

    return ia;
  }

  static boost::archive::xml_oarchive&
  stream(boost::archive::xml_oarchive& oa,
         const boost::serialization::nvp& nvp)
  {
    if(std::isnan(nvp.value())) {
      std::string nanStr = nanCStr;
      oa << boost::serialization::make_nvp(nvp.name(), nanStr);
    }
    else {
      std::stringstream oStrm;
      oStrm << std::setprecision(std::numeric_limits::digits10 + 1)
            << nvp.value();
      std::string oStr = oStrm.str();
      oa << boost::serialization::make_nvp(nvp.name(), oStr);
    }
    return oa;
  }
};

Другое аналогичные функции селектора потока могут быть добавлены для обработки большего количества типов (например, float, long double) и более специальных случаев, таких как бесконечности.

Live demo: Open In Coliru

29
задан Michael Mrozek 11 September 2010 в 23:29
поделиться