gpt4 book ai didi

c++ - 检测 CRTP 基类的 sibling

转载 作者:行者123 更新时间:2023-11-30 04:27:48 25 4
gpt4 key购买 nike

我正在尝试使用 boost::is_base_of为了检测 CRTP 基类 Generic可以识别它的同行,即 T 的类也是来源于。

如图Generic<T>::init() ,我想使用这些机制来允许类 Generic<T>添加指向其同行之一的函数的指针 Bar1Bar2 (T 也从中派生)到 map 。遗憾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;
}

//////////////////////////////////////////////////////////////////////////////////////

gcc 错误信息:

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>在 map 中以便快速访问。 setValue的选择调用取决于一个字符串,因此是 map 。另一类X可以继承Bar1Bar3但不是 Bar2 ,和以前一样,我必须存储指向适当的 setValue 的指针。用于快速访问。 Generic<T>旨在为 Foo 履行此职责, X等等

最佳答案

杰是对的。我进行了以下更改,这似乎有效。

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

关于c++ - 检测 CRTP 基类的 sibling ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10619381/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com