Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Boost.Convert with Standard Algorithms

Boost , Chapter 1. Boost.Convert 2.0 , Chapter 1. Boost.Convert 2.0

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

Следующий код демонстрирует неудачную попытку (и одна из причин).Boost.Convertбыл разработан для преобразования нескольких<string>s в<int>s с<boost::lexical_cast>:

boost::array<char const*, 3> strs = {{ " 5", "0XF", "not an int" }};
std::vector<int>             ints;
try
{
    std::transform(strs.begin(), strs.end(), std::back_inserter(ints),
        boost::bind(boost::lexical_cast<int, string>, _1));
    BOOST_TEST(0 && "Never reached!");
}
catch (std::exception&)
{
    BOOST_TEST(ints.size() == 0); // No strings converted.
}

Если же это нежелательное поведение, то.поддерживает это. Кроме того, он также обеспечивает непрерывный процесс:

boost::array<char const*, 3> strs = {{ " 5", "0XF", "not an int" }};
std::vector<int>             ints;
std::transform(strs.begin(), strs.end(), std::back_inserter(ints),
    boost::cnv::apply<int>(boost::cnv::lexical_cast()).value_or(-1));
BOOST_TEST(ints.size() == 3);
BOOST_TEST(ints[0] == -1); // Failed conversion does not throw.
BOOST_TEST(ints[1] == -1); // Failed conversion does not throw.
BOOST_TEST(ints[2] == -1); // Failed conversion does not throw.

Развертывание<boost::cnv::cstream>с лучшими возможностями форматирования дает лучшие результаты при все еще поддерживаемых процессах свертывания и неброска:

boost::array<char const*, 3> strs = {{ " 5", "0XF", "not an int" }};
std::vector<int>             ints;
boost::cnv::cstream           cnv;
try
{
    std::transform(strs.begin(), strs.end(), std::back_inserter(ints),
        boost::cnv::apply<int>(boost::cref(cnv(std::hex)(std::skipws))));
    BOOST_TEST(0 && "Never reached!");
}
catch (boost::bad_optional_access const&)
{
    BOOST_TEST(ints.size() == 2); // Only the first two strings converted.
    BOOST_TEST(ints[0] ==  5);    // " 5"
    BOOST_TEST(ints[1] == 15);    // "0XF"
    // "not an int" causes the exception thrown.
}

std::transform(strs.begin(), strs.end(), std::back_inserter(ints),
    boost::cnv::apply<int>(boost::cref(cnv(std::hex)(std::skipws))).value_or(-1));
BOOST_TEST(ints.size() == 3);
BOOST_TEST(ints[0] ==  5);
BOOST_TEST(ints[1] == 15);
BOOST_TEST(ints[2] == -1); // Failed conversion

[Important]Important

Одним из заметных отличий в развертывании<boost::cnv::cstream>с алгоритмами является использование<boost::cref>(или<std::cref>в C++11).

Следует помнить, что со стандартными алгоритмами развернутый преобразователь должен бытькопируемымилиподвижным (C++11)и фактически копируется или перемещается соответствующим алгоритмом перед использованием. Если же<std::cstringstream>не является копируемым,<boost::cnv::cstream>также не является копируемым. Это ограничение обычно обрабатывается с использованием<boost::ref>или<boost::cref>.

А теперь пример алгоритмического преобразования в формате от целого к струне с использованием форматирования<std::hex>,<std::uppercase>и<std::showbase>:

boost::array<int, 3>     ints = {{ 15, 16, 17 }};
std::vector<std::string> strs;
boost::cnv::cstream       cnv;
cnv(std::hex)(std::uppercase)(std::showbase);
std::transform(ints.begin(), ints.end(), std::back_inserter(strs),
    boost::cnv::apply<string>(boost::cref(cnv)));
BOOST_TEST(strs.size() == 3);
BOOST_TEST(strs[0] ==  "0XF"); // 15
BOOST_TEST(strs[1] == "0X10"); // 16
BOOST_TEST(strs[2] == "0X11"); // 17

Forced TypeIn vs. Deduced

До сих пор было достаточно четко указать только один тип<boost::cnv::apply<TypeOut>>— целевойтипOutтип. ИсточникТипInтип был предоставлен неявно через алгоритм и часто все это просто работает (как показывают примеры выше). Однако иногда требуется больше контроля в отношении.Тип Втип и<boost::cnv::apply()>обеспечивает такой контроль посредством явной спецификацииТип В—<boost::cnv::apply<TypeOut,TypeIn>>.

Следующий пример демонстрирует интересный вопрос, связанный с классом<change>, введенным вИнтеграция типов, определенных пользователем. Класс по существу является прославленным<enum>, удобным для пользователя (и более безопасным в мире C++03) удобным обертыванием вокруг фактического<enumvalue_type {no,up, dn}>. В частности, массив<change>значений<chgs1>чувственно преобразуется в читаемые строки «нет», «вверх» и «дн»<strs1>, когда массив<change::value_type>значений<chgs2>преобразуется в неясные «0», «1» и «2»<strs2>.

boost::array<change, 3>             chgs1 = {{ change::no, change::up, change::dn }};
boost::array<change::value_type, 3> chgs2 = {{ change::no, change::up, change::dn }};
std::vector<std::string>            strs1;
std::vector<std::string>            strs2;
std::vector<std::string>            strs3;
boost::cnv::cstream                   cnv;
std::transform(chgs1.begin(), chgs1.end(), std::back_inserter(strs1),
    boost::cnv::apply<string>(boost::cref(cnv))); // Deduced TypeIn is 'change'
std::transform(chgs2.begin(), chgs2.end(), std::back_inserter(strs2),
    boost::cnv::apply<string>(boost::cref(cnv))); // Deduced TypeIn is 'change::value_type'
BOOST_TEST(strs1.size() == 3);
BOOST_TEST(strs1[0] == "no");
BOOST_TEST(strs1[1] == "up");
BOOST_TEST(strs1[2] == "dn");
BOOST_TEST(strs2.size() == 3);
BOOST_TEST(strs2[0] == "0");
BOOST_TEST(strs2[1] == "1");
BOOST_TEST(strs2[2] == "2");

<boost::cnv::apply<TypeOut,TypeIn>>с принудительным (а не выведенным)TypeInприходит на помощь и преобразует массив<change::value_type>значений<chgs2>в чувственное «нет», «вверх» и «дн»<strs3>:

std::transform(chgs2.begin(), chgs2.end(), std::back_inserter(strs3),
    boost::cnv::apply<string, change>(boost::cref(cnv)));
BOOST_TEST(strs3.size() == 3);
BOOST_TEST(strs3[0] == "no");
BOOST_TEST(strs3[1] == "up");
BOOST_TEST(strs3[2] == "dn");

[Note]Note

Для демонстрационных целей приведенный выше пример является как можно более простым, и, следовательно, описанная "проблема", вероятно, может быть рассмотрена другими способами. Тем не менее, не позволяйте моей неспособности придумать лучший (сложный, но короткий и сочный) пример помешать оценить описанную функциональность. Я не ожидаю, что он будет использоваться часто, но он здесь, когда вам это нужно.


PrevUpHomeNext

Статья Boost.Convert with Standard Algorithms раздела Chapter 1. Boost.Convert 2.0 Chapter 1. Boost.Convert 2.0 может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: Chapter 1. Boost.Convert 2.0 ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-20 04:41:35/0.004817008972168/0