Не совсем понятно, зачем и чего вы там ищете. Если у вас есть и иерархия классов, и вам просто нужно времени компиляции определить доступен ли метод указанного имени и указанной сигнатуры, то вы можете воспользоваться моим SFINAE-детектором. Для этого вам понадобится поддержка с++11 Мой детектор корректно умеет обрабатывать перегрузку функций-членов. При этом учитывает что функция член может иметь квалификатор const. Правила доступности - аналогичны правилам доступности методов в языке с++ Есть проблемы для компиляторов вижал студии (плохая поддержка стандарта с++11) Подробности вы можете узнать здесь: http://www.gamedev.ru/code/forum/?id=184871http://ideone.com/ObElnuКод | #include <iostream> #include <type_traits> using namespace std; #define DETECTED_MEMBER(member_name) \ template<typename C, typename T>class has_##member_name \ { \ template<class U> static constexpr auto Check(U*) -> typename \ std::is_same< decltype( std::declval<U>().member_name), T >::type; \ \ template<typename> static constexpr std::false_type Check(...); \ typedef decltype(Check<C>(0)) Result; \ public: \ enum { eIS_NOCONST = 0 }; \ enum { eIS_CONST = 0 }; \ enum { eIS_AVAILABLE = Result::value }; \ }; \ template<class C,typename R, typename... Args>class has_##member_name<C, R(Args...)> \ { \ typedef R(C::*Method)(Args...); typedef R(C::*CMethod)(Args...)const; \ template <class U> using NoConst = decltype(static_cast<Method> (&U::member_name)); \ template <class U> using Const = decltype(static_cast<CMethod>(&U::member_name)); \ \ template<class U> static constexpr std::true_type CheckNoConst( NoConst<U>*p ); \ template<class> static constexpr std::false_type CheckNoConst(...); \ typedef decltype(CheckNoConst<C>(0)) NoConstResult; \ \ template<class U> static constexpr std::true_type CheckConst( Const<U>*p); \ template<class> static constexpr std::false_type CheckConst(...); \ typedef decltype(CheckConst<C>(0)) ConstResult; \ public: \ enum { eIS_NOCONST = NoConstResult::value }; \ enum { eIS_CONST = ConstResult::value }; \ enum { eIS_AVAILABLE = eIS_NOCONST | eIS_CONST }; \ }; #define is_available(class_name, member_type, member_name) has_##member_name<class_name, member_type>::eIS_AVAILABLE #define is_available_method(class_name, member_type, member_name) has_##member_name<class_name, member_type>::eIS_NOCONST #define is_available_cmethod(class_name, member_type, member_name) has_##member_name<class_name, member_type>::eIS_CONST //------------------------------------------------------------------------------------ int g; struct A //<---- для эксперимента будем определять доступность методов и данных { A():r(g){} void fooA(int); void fooA(int)const; void fooA(); void fooA()const; int v; int& r; int a[10]; int* p; int** pp; private: void private_foo(); }; struct B : A //<---- используем наследование, { //что бы продемонстрировать определение доступности методов в базовых классах int v; int fooB(){ return 0; } };
//указываем имена мемберов, доступность которых хотим определить DETECTED_MEMBER(fooA); DETECTED_MEMBER(fooB); DETECTED_MEMBER(v); DETECTED_MEMBER(r); DETECTED_MEMBER(a); DETECTED_MEMBER(p); DETECTED_MEMBER(pp); DETECTED_MEMBER(private_foo); int main() { //синтаксис: is_available( имя_класса , тип_мембера , имя_мембера) //вернет true если мембер доступен, иначе - false //---- детектирование данных cout<< "is available int B.v ? " << is_available(B,int,v) <<endl; cout<< "is available int& B.r ? " << is_available(B,int&,r) <<endl; cout<< "is available int B.a[10] ? " << is_available(B,int[10],a) <<endl; cout<< "is available int* B.p ? " << is_available(B,int*,p) <<endl; cout<< "is available int* B.pp ? " << is_available(B,int**,pp) <<endl; //---- детектирование методов cout<< "is available void B.fooA(int) or void B::fooA(int)const ? " <<is_available(B,void(int),fooA) <<endl; cout<< "is available void B.fooA(int) ? " << is_available_method(B,void(int),fooA) <<endl; cout<< "is available void B.fooA(int)const ? " << is_available_cmethod(B,void(int),fooA) <<endl; cout<< "is available int B.fooB() ? " << is_available_method(B,int(),fooB) <<endl; cout<< "is available void B.private_foo() ? " << is_available(B,void(),private_foo) <<endl; }
|
Это сообщение отредактировал(а) Lukkoye - 30.6.2014, 22:19
|