Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Декомпозиция любого Callable, C+0x 
:(
    Опции темы
Abyx
Дата 23.7.2010, 09:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 1
Всего: 10



Задача: написать метафункции, позволяющие произвести декомпозицию произвольного Callable типа - получить тип возвращаемого значения и типы аргументов.
Код должен быть ориентирован на С++0х компилятор, минимум msvs2010 и gcc4.5, в перспективе и clang.

-----------------

На данный момент есть метафункции, решающие похожие задачи - это
function_traits из boost.type_traits, которая позволяет производить декомпозицию типов R(T1, T2, ... TN)
и parameter_types, result_type из boost.function_types, которая позволяет производить декомпозицию функций, ссылок на функции, указателей на функции, указателей на функции-члены.

-----------------

Надо обеспечить малое время компиляции.
PM MAIL   Вверх
Abyx
Дата 23.7.2010, 11:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 1
Всего: 10



с функциями не-членами все просто:
отрезаем от нее указатель, и применяем function_traits
Код

template<typename T, bool isClass = std::is_class<T>::value> struct param_type;

template<typename T>
struct param_type<T, false>
{
    typedef typename boost::function_traits<typename std::remove_pointer<T>::type> type;
};

а с функторами все интереснее.

Можно получить operator(), 
Код

decltype(&T::operator())

и передать его в boost.function_types
но boost.function_types медленная, т.к. возвращает boost::mpl::vector.

Можно попробовать поступить хитро, и отрезать у decltype(&T::operator()) класс - преобразовать в указатель на функцию не-член
Код

template<typename T, class C>
static T* mem_ptr_to_ptr_helper(T C::*)
{
    return (T*)0;
}

template<typename T>
struct param_type<T, true>
{
    typedef boost::function_traits<
        typename std::remove_pointer<decltype(mem_ptr_to_ptr_helper(&T::operator()))>::type
    > type;    
};

однако этот код не работает в MSVC, т.к. 
decltype(mem_ptr_to_ptr_helper(&T::operator())) имеет тип RetT (__thiscall*)(ArgT)
затем
typename std::remove_pointer<decltype(mem_ptr_to_ptr_helper(&T::operator()))>::type имеет тип RetT __cdecl (ArgT)
( __thiscall превратился в __cdecl ! o_O )
а boost::function_traits не понимает типы вида R __convention(...)
Надо как-то избавляться от __cdecl

Это сообщение отредактировал(а) Abyx - 23.7.2010, 12:11
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0472 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.