我想知道模板函数中类型类T的父类是什么,假设我有以下类:
class A{
...
}
class B: public A{
...
}
class C: public B{
...
}
template<typename T>
size_t getBaseHashCode()
{
return typeid(base_of(T)).hashcode();
}
int main()
{
A a;
C c;
size_t size = getBaseHashCode<C>();// must return hashcode of class B
}
无论如何都要找到类型为T的父类并实现base_of函数?
编辑: 我的确要做的是:
我是为我创建对象的工厂类:
template <typename B>
class Factory{
public:
template <typename D>
void registerType(std::string name)
{
static_assert(std::is_base_of<B, D>::value, "class doesn't derive from the base");
table_[name] = &createFunc<D>;
}
B* create(std::string name)
{
const auto it = table_.find(name);
if(it != table_.end())
return it->second();
FILE_LOG(logERROR) << "unidentified option, acceptable options are:";
for(auto const &m : list())
FILE_LOG(logERROR) << '\t' << m;
return nullptr;
}
std::vector<std::string> list()
{
std::vector<std::string> lst;
for(auto const &iter : table_)
lst.push_back(iter.first);
return lst;
}
private:
template<typename D>
static B* createFunc()
{
return new D();
}
typedef B* (*PCreateFunc)();
std::map<std::string, PCreateFunc> table_;
};
在registerType函数中我想设置D类型的一些属性或它的父类,然后在create函数中,我想基于它创建对象。
答案 0 :(得分:1)
您也可以考虑使用一些父包装来自动化typedef
:
#include <type_traits>
#include <typeinfo>
#include <iostream>
template <class P>
struct base: P {
using base_type = P;
};
struct A{ };
struct B: base<A>{ };
struct C: base<B>{ };
template <class T>
auto base_of(T) -> typename T::base_type;
template <class T>
using base_of_t = decltype(base_of(std::declval<T>()));
int main() {
std::cout << typeid(base_of_t<C>).name() << std::endl;
}
输出:
1B
c++filt -t 1B
的输出:
乙
注意它仍然不处理多重继承
答案 1 :(得分:0)
您可以使用一些您不必定义的函数声明 它遵循一个最小的工作示例:
#include<utility>
#include<typeinfo>
#include<iostream>
class A{};
class B: public A{};
class C: public B{};
B base_of(const C &);
A base_of(const B &);
template<typename T>
void getBaseHashCode() {
std::cout << typeid(decltype(base_of(std::declval<T>()))).name() << std::endl;
}
int main() {
getBaseHashCode<B>();
getBaseHashCode<C>();
}
它利用了这样一个事实:在这种情况下,你在调用期间有完全匹配。它是一个相当弱的解决方案,但可以使用问题中的示例代码。
那就是说,我同意整个问题看起来像一个XY问题。
修改强>
正如@ Jarod42在评论中提到的那样,一种更惯用(和冗长)的方式是使用特征。
它遵循一个最小的工作示例:
#include<typeinfo>
#include<iostream>
class A{};
class B: public A{};
class C: public B{};
template<typename> struct base_of;
template<> struct base_of<B> { using type = A; };
template<> struct base_of<C> { using type = B; };
template<typename T>
void getBaseHashCode() {
std::cout << typeid(typename base_of<T>::type).name() << std::endl;
}
int main() {
getBaseHashCode<B>();
getBaseHashCode<C>();
}
这也将解决由于多重继承而导致的问题。 base_of
专业化的设计者将负责将其中一个基类推广到首选的角色。