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;
}