我的图书馆用户将通过getInstance<T>()
要求提供任何课程的实例。
用户在某个程序中询问(调用{T1,T2,T3,...,Tn}
的外观)的所有类getInstance<T>()
中,如果有一对(i,j)
和Ti
派生自{{ 1}},我只会创建更大的一个,例如Tj
。
这是一个例子 假设用户的代码代码要求我创建这些类: -
图形
他们的继承如下: -
(以上四个类在图中标有黄色。)
我的代码将创建覆盖整棵树的最小数量的类实例
在这种情况下,最佳解决方案是 3 :Ti
,Rigid
,Constraint
。
粗略地说,三个箭头传递树中的所有类。
在这种情况下,会有Graphic
的2个实例,但我不在乎。 (感谢Christian Hackl)
更具体地说,Physic
可以返回任何一个
基础类型可以是getInstance<Physic>()
或Rigid*
- 两者都可以。
如果有很多最低解决方案,那么其中任何一个都可以。
这就是我的梦想: -
Constraint*
怎么做?
这是最接近的问题:Create "custom typeid" for many types AND cache their sizeof()
我觉得有可能:我必须使用以下方法缓存类型: -
//..... some list to cache std::function .... ?
template<class T> T* getInstance(){
//return new T() ?
}
class B{};
class C{};
class D : public B{};
int main(){
//..... allow to insert some code here ...... (a little less preferable)
B* b=getInstance<B>(); //return B* (implicitly cast D*->B*)
C* c=getInstance<C>(); //return C*
D* d=getInstance<D>(); //return D*
assert( static_cast<D*>(b) == d );
delete d; delete c;
//no memory leak
}
- &gt;将其保存在列表中std::function
。 然而,这远非一个具体的想法。
我想为我的图书馆+教育目的创建一个非常复杂的单身经理 我知道这不是一个好习惯,但我相信这个解决方案会启发我在C ++领域 以防它不是那么明显 - 这不是作业/面试。 子>
答案 0 :(得分:1)
你主要需要一个类型特征,给定一个类型和一个类型列表,从列表中返回一种顶级派生类型。
不是很优雅(我试着把它简化一下)但是下面的代码应该给你一个例子
#include <cassert>
#include <iostream>
#include <type_traits>
struct core {};
struct physic : public core {};
struct rigid : public physic {};
struct constraint : public physic {};
struct graphic : public core {};
template <typename ... Ts>
struct contTypes
{ };
template <typename T0, typename T1>
struct isStrictBase
{ static constexpr bool value =
(false == std::is_same<T0, T1>::value)
&& (true == std::is_base_of<T0, T1>::value); };
template <bool, typename...>
struct chooseT;
template <typename, typename, typename>
struct getTopTypeH;
template <typename C0, typename T, typename T0, typename C1>
struct chooseT<true, C0, T, T0, C1>
{ using type = typename getTopTypeH<C0, T0, C0>::type; };
template <typename C0, typename T, typename T0, typename C1>
struct chooseT<false, C0, T, T0, C1>
{ using type = typename getTopTypeH<C0, T, C1>::type; };
template <typename, typename, typename>
struct getTopTypeH;
template <template <typename ...> class Ct, typename ... Ts0, typename T>
struct getTopTypeH<Ct<Ts0...>, T, Ct<>>
{ using type = T; };
template <template <typename ...> class Ct, typename ... Ts0,
typename T, typename T0, typename ... Ts>
struct getTopTypeH<Ct<Ts0...>, T, Ct<T0, Ts...>>
{
using type = typename chooseT<isStrictBase<T, T0>::value,
Ct<Ts0...>, T, T0, Ct<Ts...>>::type;
};
template <typename T, typename CT>
struct getTopType
{ using type = typename getTopTypeH<CT, T, CT>::type; };
template <typename T>
struct staticWrapper
{
static T * getPnt ()
{
static T st{};
return & st;
}
};
using cT = contTypes<core, physic, rigid, constraint, graphic>;
template <typename T>
T * getInstance ()
{ return staticWrapper<typename getTopType<T, cT>::type>::getPnt(); }
int main ()
{
auto p0 = getInstance<core>();
auto p1 = getInstance<physic>();
auto p2 = getInstance<rigid>();
auto p3 = getInstance<constraint>();
auto p4 = getInstance<graphic>();
assert( p0 == p1 );
assert( p0 == p2 );
std::cout << "assert passed" << std::endl;
}