Открыть список
Как стать автором
Обновить

Комментарии 21

Спасибо, в очередной раз остался доволен своим выбором…
А winAPI писали для роботов.
Его писали на plain C, там не очень-то разгуляешься.
НЛО прилетело и опубликовало эту надпись здесь
COM вообще не из C++, это двоичный стандарт. Удобнее всего с ним работать из VB или Jscript через Automation, как мне кажется.
А в C++ для работы с ним есть ATL.
Как бы glibc таки поприятнее будет.
А есть ли там функции для работы с HTTP? Я хотел посмотреть, как они устроены, но сходу не нашел.
Не такой и плохой АПИ имхо.
Я куда хуже видал)
>> В идеале хочется получать значение заголовка в одной строке кода:

>> const int code = get_header<HTTP_QUERY_STATUS_CODE>(hRequest);
>> const int responseBodySize = get_header<HTTP_QUERY_CONTENT_LENGTH>(hRequest);
>> const CString allHeaders = get_header<HTTP_QUERY_RAW_HEADERS_CRLF>(hRequest);

Как по мне, так в идеале хотелось бы писать примерно вот-так:
const header_t header = request.header();
const int status = header.statusCode();
const header_t::body_t body = header.responseBody(); 
// header_t::body_t какая-то структура типа вектора, возможно ref-counting 
// и хранящая внутри указатель, во избежание копирования
const size_t bodyLength  = body.size(); // итд


— Также, помоему вы немного не верно толкуете идиому trait.
Сверьтесь с сылками отсюда: en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Traits

— По сути дела вы связали значения констант со способом добычи результата.
Думаю в зависимости от контекста это можно было бы сделать и проще с помощью того же mpl или в run-time c помощью обычных макросов

PS: Мои поправки не имеют отношения к вашей идее, только к ее применению, названию и способу использования. Сама идея, думаю, вполне жизнеспособна.
FIX:
>> или в run-time c помощью обычных макросов
или в run-time c помощью обычных map-ов и функторов.

пора идти спать
>> const header_t header = request.header();
>> const int status = header.statusCode();

Согласен, это еще лучше, но реализовывать такое я бы стал точно так же.

>> — Также, помоему вы немного не верно толкуете идиому trait.
>> Сверьтесь с сылками отсюда: en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Traits

Я был в этих ссылках.
Да, классические traits зависят от типа, а не от константы, но суть от этого не меняется — вычисление типа (типов) на этапе компиляции.
Если сделать это в run-time, то тип придется приводить ручками, а это нехорошо.
А как это сделать с помощью mpl?
Я буст очень люблю и постоянно использую, но именно в mpl не силен.
Но все же попробую из азарта :)

#include <boost/mpl/map.hpp>
#include <boost/mpl/at.hpp>

#include <boost/mpl/int.hpp>

#include <boost/config.hpp>

#include <iostream>
#include <string>



// accessor functions stubs
// in these function you will obtain value with HttpQueryInfo by valueCode
template< typename ResultT >
ResultT get_value( int valueCode );

template<  >
std::string get_value< std::string >( int valueCode )
{
    return "hi!";
}

template<  >
int get_value< int >( int valueCode )
{
    return valueCode * 42;
}



using namespace boost::mpl; // just for simplify

// mpl::map valueCode on result type
typedef map<
                pair< int_< 0 >, int >,
                pair< int_< 1 >, int >,
                pair< int_< 2 >, std::string >,
                pair< int_< 3 >, int >
            >	test1;


// helper structure which help us to avoid to use 
// long  - at< test1, int_< i > >::type 
template< int i >
struct toResultType
{
    typedef typename at< test1, int_< i > >::type type;
};



// interface function
template < int i >
typename toResultType< i >::type func()
{
    return get_value< toResultType< i >::type  > ( i );
}



int
main()
{
    std::cout << func<0>() << "\n"
              << func<1>() << "\n"
              << func<2>() << "\n"
              << func<3>() << "\n";
}



Упрощенный ваш пример.
Еще надо будет попробовать связать разные ф-цие с разными valueCode.
Сейчас идет связка тип — valueCode.
браво)
но по сути у вас пока только кучка специализаций заменена на mpl::map
кстати, это
pair< int_< 0 >, int >,
я бы все равно заменил на макрос с говорящим названием, чтобы было нагляднее тому, кто будет добавлять новые константы

далее для того, чтобы привязать метод к константе, скорее всего придется совать в этот map структуры вроде num_getter
> но по сути у вас пока только кучка специализаций заменена на mpl::map
выходит, что да :)

> я бы все равно заменил на макрос с говорящим названием
макросов боюсь, и стараюсь избегать :)
для упрощения понимания можно было-бы сделать, что-то вроде:
template < int i, typename T >
struct bindValueCodeOnResultType
{
	typedef typename pair< int_< i >, T > type;
};

и в списке типов использовать

bindValueCodeOnResultType< 0, int >::type,


> далее для того, чтобы привязать метод к константе
привязывать разные функции явно впринципе не обязательно для этого случая.
это может понадобиться если к примеру, если нам надо будет по разному доставать значения одинакового типа.
и в этом случае — да, скорее всего прийдется совать структурки с operator() или каким-то методом и конструктором по умолчанию.
И только чтолбы без лишних созданий объектов, копирований строк и чтобы не парсить заголовки если нуден только код ответа!
> const header_t header = request.header();
> const int status = header.statusCode();
вот что это лучше я с вами согласен, но это абсолютно не меняет дела, внутри скорее всего будет так же как у автора.

> Думаю в зависимости от контекста это можно было бы сделать и проще с помощью того же
> mpl или в run-time c помощью обычных макросов
а тут мне все-таки кажется что макросами намного проще, быстрее и понятней, чем юзать mpl.
> вот что это лучше я с вами согласен, но это абсолютно не меняет дела, внутри скорее всего будет так же как у автора.
Только если использовать внутри WinInet. А ведь может быть и boost::asio, либо какие-то libghttp, да вообще что-угодно.

> а тут мне все-таки кажется что макросами намного проще, быстрее и понятней, чем юзать mpl.
возможно. хотя никто не мешает добавление в mpl::map задефайнить :)
автор сделал много специализаций, я же обошелся списком типов. впринципе это основная разница.
> Только если использовать внутри WinInet. А ведь может быть и boost::asio, либо какие-то libghttp, да вообще что-угодно.
я имел ввиду, что название статьи «Использование traits для обустройства Win32 API» :) поэтому внутри будет как у автора.
а по поводу mpl, то это дело вкуса :)
> я имел ввиду, что название статьи
ясно, недопонял, что вы имели ввиду.

> по поводу mpl, то это дело вкуса
да, мне на первый взгляд показалось, что с mpl проще будет и универсальнее. хотя сейчас уже кажется, что профит не такой уж и большой.
манда
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.