Я пытаюсь использовать boost::is_base_of
, чтобы определить, может ли базовый класс CRTP Generic
идентифицировать своих сверстников, то есть классы, которые также получены от T
.Обнаружение братьев и сестер базового класса CRTP
Как показано в Generic<T>::init()
, я хотел бы использовать эти механизмы для того, чтобы класс Generic<T>
добавить указатели на функции одного из его коллег Bar1
или Bar2
(из которых T
также происходит) на карте. К сожалению, boost::is_base_of
не может обнаружить классы, такие как Bar3
, что T
не происходит.
#include <iostream>
#include <cstdlib>
#include <string>
#include <typeinfo>
#include <map>
#include <boost/type_traits.hpp>
//////////////////////////////////////////////////////////////////////////////////////
template<typename T>
class Bar
{
public:
void setValue()
{
std::cout << typeid(this).name() << std::endl;
}
};
class Bar1 : public Bar<char>{};
class Bar2 : public Bar<bool>{};
class Bar3 : public Bar<long>{};
//////////////////////////////////////////////////////////////////////////////////////
template<typename T>
class Generic
{
public:
typedef void (T::*setter)();
void init();
};
template<typename T>
void Generic<T>::init()
{
std::map<std::string , Generic<T>::setter> setterMap;
if(boost::is_base_of<Bar1, T >::value) setterMap["bar1"] = &Bar1::setValue;
if(boost::is_base_of<Bar2, T >::value) setterMap["bar2"] = &Bar2::setValue;
if(boost::is_base_of<Bar3, T >::value) setterMap["bar3"] = &Bar3::setValue;
std::cout << setterMap.size() << std::endl;
}
//////////////////////////////////////////////////////////////////////////////////////
template<typename T>
class Foo : public Bar1 , public Bar2 , public Generic<Foo<T> >
{
public:
};
//////////////////////////////////////////////////////////////////////////////////////
int main()
{
Foo<int> f;
f.init();
return EXIT_SUCCESS;
}
//////////////////////////////////////////////////////////////////////////////////////
НКУ сообщение об ошибке:
In static member function ‘static void Generic<T>::init() [with T = Foo<int>]’:
error: cannot convert ‘void (Bar<long int>::*)()’ to ‘void (Foo<int>::*)()’ in assignment
Редактировать
Чтобы обеспечить некоторый контекст для этого вопроса. Я пытаюсь сохранить указатели на методы setValue
базовых классов каждого Foo<T>
на карте для быстрого доступа. Выбор setValue
для вызова зависит от строки, таким образом, от карты. Другой класс X
может наследовать Bar1
и Bar3
, но не Bar2
, и, как и прежде, мне нужно было бы сохранить указатели на соответствующий setValue
для быстрого доступа. Generic<T>
стремится выполнять эту роль Foo
, X
и т.д.
Наконец-то! Могу ли я получить голосование? Кстати, кто твой папа? Давай теперь ... скажи мне: P – Jay
Кстати, хороший пример ... У меня не было времени с тех пор, как я был в спешке, чтобы курить сорняк – Jay