C++ 检测CRTP基类的同级
我试图使用C++ 检测CRTP基类的同级,c++,inheritance,stl,sfinae,crtp,C++,Inheritance,Stl,Sfinae,Crtp,我试图使用boost::is_base_of来检测CRTP基类Generic是否可以识别它的对等类,即T也是从中派生出来的类 如Generic::init()所示,我希望使用这些机制,以便允许类Generic向其对等函数之一的Bar1或Bar2(也从中派生出T)添加指向映射的指针。不幸的是,boost::is_base\u of无法检测类,例如Bar3,而T不是从中派生的类 #include <iostream> #include <cstdlib> #include &
boost::is_base_of
来检测CRTP基类Generic
是否可以识别它的对等类,即T
也是从中派生出来的类
如Generic::init()
所示,我希望使用这些机制,以便允许类Generic
向其对等函数之一的Bar1
或Bar2
(也从中派生出T
)添加指向映射的指针。不幸的是,boost::is_base\u 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;
}
//////////////////////////////////////////////////////////////////////////////////////
#包括
#包括
#包括
#包括
#包括
#包括
//////////////////////////////////////////////////////////////////////////////////////
模板
分类栏
{
公众:
void setValue()
{
std::cout在我的脑海中,我无法想象没有中间人的情况下这项工作
是否可以创建一个用运算符重载封装所需逻辑的结构?该结构将有一个原始指针,然后您可以使用重载来遵从它,以确保它被正确使用
另一种看起来可读的方法是创建另一个作为门面的前向类,然后利用它
这与类似。Jay是正确的。我做了以下更改,这似乎有效
template <bool, typename T> struct AddSetter;
template <typename T> struct AddSetter <true, T>
{
template<typename F>
void Set (std::map<std::string , typename Generic<T>::setter>& setterMap, const std::string& key, F fn)
{
setterMap[key] = fn;
}
};
template <typename T> struct AddSetter <false, T>
{
template<typename F>
void Set (std::map<std::string , typename Generic<T>::setter>& setterMap, const std::string& key, F fn)
{
}
};
template<typename T>
void Generic<T>::init()
{
std::map<std::string , Generic<T>::setter> setterMap;
AddSetter<boost::is_base_of<Bar1, T >::value, T>().Set (setterMap, "bar1", &Bar1::setValue);
AddSetter<boost::is_base_of<Bar2, T >::value, T>().Set (setterMap, "bar2", &Bar2::setValue);
AddSetter<boost::is_base_of<Bar3, T >::value, T>().Set (setterMap, "bar3", &Bar3::setValue);
std::cout << setterMap.size() << std::endl;
}
模板结构AddSetter;
模板结构AddSetter
{
模板
空集(std::map和setterMap,const std::string和key,F fn)
{
setterMap[key]=fn;
}
};
模板结构AddSetter
{
模板
空集(std::map和setterMap,const std::string和key,F fn)
{
}
};
模板
void Generic::init()
{
std::map setterMap;
AddSetter().Set(setterMap,“bar1”和&bar1::setValue);
AddSetter().Set(setterMap,“bar2”和&bar2::setValue);
AddSetter().Set(setterMap,“bar3”和&bar3::setValue);
终于可以了!我可以投票了吗?顺便说一句,谁是你的爸爸?来吧…告诉我:PBtw,很好的例子…我没有时间,因为我正忙着抽大麻
template <bool, typename T> struct AddSetter;
template <typename T> struct AddSetter <true, T>
{
template<typename F>
void Set (std::map<std::string , typename Generic<T>::setter>& setterMap, const std::string& key, F fn)
{
setterMap[key] = fn;
}
};
template <typename T> struct AddSetter <false, T>
{
template<typename F>
void Set (std::map<std::string , typename Generic<T>::setter>& setterMap, const std::string& key, F fn)
{
}
};
template<typename T>
void Generic<T>::init()
{
std::map<std::string , Generic<T>::setter> setterMap;
AddSetter<boost::is_base_of<Bar1, T >::value, T>().Set (setterMap, "bar1", &Bar1::setValue);
AddSetter<boost::is_base_of<Bar2, T >::value, T>().Set (setterMap, "bar2", &Bar2::setValue);
AddSetter<boost::is_base_of<Bar3, T >::value, T>().Set (setterMap, "bar3", &Bar3::setValue);
std::cout << setterMap.size() << std::endl;
}