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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> приведение указателя на метод в иерархии классов 
V
    Опции темы
djamshud
Дата 15.10.2010, 09:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 8
Всего: 39



mes, не увеличивает. И более того у меня в гцц-4.4.4 функции, переданные в качестве аргументов шаблонов, вообще никогда не инлайнятся. Что странно.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
mes
Дата 15.10.2010, 09:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

Репутация: 144
Всего: 250



а тело функции доступно ?


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 15.10.2010, 09:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(georain @  15.10.2010,  09:09 Найти цитируемый пост)
А что интересно?


Цитата(boostcoder @  15.10.2010,  08:28 Найти цитируемый пост)
микрософтстудия?
у кого есть такой компилятор, скажите пожалуйста, что говорит на такие выражения


вот полный код:
Код

#include <tuple>
#include <boost/tuple/tuple.hpp>
#include <boost/fusion/tuple.hpp>

template<typename... Args>
struct std_tuple_type {
   typedef typename std::tuple<Args...> type;
};


template<typename... Args>
struct boost_tuple_type {
   typedef typename boost::tuple<Args...> type;
};


template<typename... Args>
struct fusion_tuple_type {
   typedef typename boost::fusion::tuple<Args...> type;
};

int main() {
   typedef std_tuple_type<char, int, int> std_tuple;
   typedef boost_tuple_type<char, int, int> boost_tuple;
   typedef fusion_tuple_type<char, int, int> fusion_tuple;
}


http://liveworkspace.org/code/0662bfe307bb...b4a3d2738e1d4fa

если кто проверит, буду очень признателен.

PM WWW   Вверх
georain
Дата 15.10.2010, 09:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(mes @  15.10.2010,  09:13 Найти цитируемый пост)
т.е. смысла строить шаблон вместо того чтоб вызвать напрямую, нет, если только там не делается особых проверок .. 
но тогда варианты с передачей функции как  параметра шаблона, так и параметра шаблонной функции  равнозначны, при условии передачи ее как констатного выражения.. так как второй вариант может принимать и указатели .. 

Дело ещё и в том что мне нужно сгенерировать функцию которая будет принимать указатель на вызываемый метод, и передать её адрес, при этом адрес метода теряется, а хранить и передавать его - это дополнительные расходы в рантайме, пример:
Код

    template <
                typename ClassType,
                Condition(ClassType::*MemFunCallback)(Result&)
             >
    static Condition CallbackFunction(SFHandler * handler, .... .... .... ....)
    {
        // тут всякая функциональность
                // ....
        return ( static_cast<ClassType*>(handler)->*MemFunCallback )(result);
    }

    // шаблон процедуры вызова
    template <
                typename ClassType,
                Condition(ClassType::*MemFunCallback)(Result&)
             >
    static void Call( ..... ..... ){
        // статическое создание и получение адреса функции обратного вызова
        static const CallbackType * callback = CallbackFunction<ClassType, MemFunCallback>;
        // передача этого адреса в функцию
        .....->createInquiry(..., callback, ...);

В метод createInquiry я передаю только адрес callback, это 4 или 8 байт, адрес же метода я так не передам потому что типы классов разные, к тому же он может достигать 12 байт в длину, короче это ещё и накладно

Добавлено @ 09:49
В общем ClassType должен быть классом, в котором находится метод, что печально
А на счет constexpr вы опять правы, но в документации по шаблонам сказано что "параметры шаблона не являющиеся типами могут быть: целочисленный тип или тип перечисления, тип указателя, включая указатели на обычные объекты, функции и члены классов, ссылочный тип (как ссылки на объекты, так и ссылки на функции)" конец цитаты C++ Templates The Complete Guide 2003

Добавлено @ 09:57
кстати, вопрос на засыпку, как из типа указателя на метод класса получить тип класса? это бы очень пригодилось

Это сообщение отредактировал(а) georain - 15.10.2010, 09:57
PM MAIL   Вверх
mes
Дата 15.10.2010, 10:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

Репутация: 144
Всего: 250



Цитата(georain @  15.10.2010,  08:42 Найти цитируемый пост)
"параметры шаблона не являющиеся типами могут быть: целочисленный тип или тип перечисления, тип указателя
есть тип, а есть значение... а значение одного и того же типа может быть известно в компиль тайм, а может и нет 
smile



--------------------
PM MAIL WWW   Вверх
georain
Дата 15.10.2010, 10:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(djamshud @  15.10.2010,  09:17 Найти цитируемый пост)
у меня в гцц-4.4.4 функции, переданные в качестве аргументов шаблонов, вообще никогда не инлайнятся.

да, проверьте доступно ли тело функции в точке инстанциирования шаблона, и попробуйте inline __attribute__((always_inline)), он кстати что-то пишет если не может проинлайнить

Добавлено через 1 минуту и 51 секунду
Цитата(mes @  15.10.2010,  10:02 Найти цитируемый пост)
есть тип, а есть значение... а значение одного и того же типа может быть известно в компиль тайм, а может и нет 

это понятно, но
Код

static void(Derived::* const Foo )(void) =  &Derived::foo;

доступно в компиль тайм 
PM MAIL   Вверх
mes
Дата 15.10.2010, 10:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

Репутация: 144
Всего: 250



Цитата(georain @  15.10.2010,  09:02 Найти цитируемый пост)
доступно в компиль тайм  

неа... значение указателя не является известным_в_компиль_тайм.. не смотря на кажушуюся известность..

в общем сравните два выражения :
Код

const i =5;           // const 
enum { e = 5  }; // constexpr


Добавлено через 1 минуту и 24 секунды
и то что константой  можно инициализировать массивы, ничего не говорит.. это обходной трюк, из за неимения альтернативных средств.. 



--------------------
PM MAIL WWW   Вверх
georain
Дата 15.10.2010, 10:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



=(
А ведь такой код верный:
Код

template<int x>
int r(){ return x; }

static const int c = 5;

int k(){
    return r<c>();
}


Это сообщение отредактировал(а) georain - 15.10.2010, 10:21
PM MAIL   Вверх
mes
Дата 15.10.2010, 10:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

Репутация: 144
Всего: 250



Цитата(georain @  15.10.2010,  09:18 Найти цитируемый пост)
А ведь такой код верный

ага верный.. предыдущий пример я привел для понимания разницы.. 
а верный он благодаря 
Цитата(mes @  15.10.2010,  09:15 Найти цитируемый пост)
это "обходной трюк"

сейчас ... 


--------------------
PM MAIL WWW   Вверх
baldina
Дата 15.10.2010, 10:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата

кстати, вопрос на засыпку, как из типа указателя на метод класса получить тип класса? это бы очень пригодилось


вероятно никак. да и не нужно, т.к. (нестатический) метод может быть вызван только в применении к объекту, а тип объекта в рантайм известен
PM MAIL   Вверх
mes
Дата 15.10.2010, 10:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

Репутация: 144
Всего: 250



Цитата

5.19 Constant expressions 
In several places, C + + requires expressions that evaluate to an integral or enumeration constant: as array
bounds (8.3.4, 5.3.4), as case expressions (6.4.2), as bit-field lengths (9.6), as enumerator initializers (7.2),
as static member initializers (9.4.2), and as integral or enumeration non-type template arguments (14.3).

An integral constant-expression can involve only literals (2.13), enumerators, const variables or static
data members of integral or enumeration types initialized with constant expressions
 (8.5), non-type template
parameters of integral or enumeration types, and sizeof expressions. Floating literals (2.13.3) can
appear only if they are cast to integral or enumeration types. Only type conversions to integral or enumeration
types can be used. In particular, except in sizeof expressions, functions, class objects, pointers, or
references shall not be used
, and assignment, increment, decrement, function-call, or comma operators shall
not be used.


Добавлено через 14 минут и 20 секунд
Цитата(georain @  15.10.2010,  08:42 Найти цитируемый пост)
кстати, вопрос на засыпку, как из типа указателя на метод класса получить тип класса? это бы очень пригодилось

если я правильно понял smile
Код

#include <iostream>

struct A { void f() {}; };
struct B { void f() {}; };


void print_classname (A*) { std::cout << "A"; }
void print_classname (B*) { std::cout << "B"; }

template <class T>
void print_classname ( void (T::*memfn)())
{
   print_classname ((T*)(NULL));
}
int main () {
   print_classname (&B::f);
   print_classname (&A::f);
}



Это сообщение отредактировал(а) mes - 15.10.2010, 10:57


--------------------
PM MAIL WWW   Вверх
georain
Дата 16.10.2010, 02:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(baldina @  15.10.2010,  10:46 Найти цитируемый пост)
вероятно никак. да и не нужно

Если я узнаю тип класса из указателя на метод, то смогу подставить его в шаблонный параметр для решения проблемы

Цитата(mes @  15.10.2010,  10:57 Найти цитируемый пост)
если я правильно понял

Вы правильно меня поняли, и теперь я смогу это сделать!

Код

template <typename Class, typename Result, typename... Arguments>
Class ClassFromMemFunPtr(Result (Class::*)(Arguments...));

typedef decltype(ClassFromMemFunPtr(&Derived::moo)) ClassType1;
// ClassType1 == Derived

typedef decltype(ClassFromMemFunPtr(&Derived::foo)) ClassType2;
// ClassType2 == Base


Вы помогли мне разобраться со всеми возникшими вопросами, спасибо большое!
PM MAIL   Вверх
boostcoder
Дата 13.1.2011, 00:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(georain @  15.10.2010,  09:42 Найти цитируемый пост)
кстати, вопрос на засыпку, как из типа указателя на метод класса получить тип класса? это бы очень пригодилось

так:
Код

#include <iostream>

#include <boost/function_types/is_member_function_pointer.hpp>
#include <boost/function_types/components.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/assert.hpp>

struct type {
   void method() { std::cout << "type::method()" << std::endl; }
};

template<typename MP>
struct class_type {
   static_assert(
      boost::function_types::is_member_function_pointer<MP>::value,
      "in class_type<MP>: MP is not member function pointer!"
   );
   typedef typename boost::mpl::at_c<
      typename boost::function_types::components<
         MP,
         boost::mpl::identity<boost::mpl::_1>
      >::types,
      1
   >::type type;
};

typedef void(type::*member_ptr)();

int main() {
   class_type<member_ptr>::type obj;
   obj.method();
}

http://liveworkspace.org/code/93c11e03d459...18545bef566a57d

Up.
все же static_assert() предоставляемый компилятором, поудобней ;)

Это сообщение отредактировал(а) boostcoder - 13.1.2011, 03:09
PM WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.1379 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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