Request Short Link
C++ 98
C++ 11
C++ 14
C++ 17
C++ 20
C++ 23
C++ 2c
for-loops as while-loops
array subscription
Show all implicit casts
Show all template parameters of a CallExpr
Use libc++
Transform std::initializer_list
Show noexcept internals
Show padding information
Show coroutine transformation
Show C++ to C transformation
Show object lifetime
Default
15
18
20
22
26
More
GitHub
Patreon
Issues
About
Policies
Examples
C++ Insights @ YouTube
Settings
Version
Need in-house C++ training? Learn more here
×
Made by
Andreas Fertig
Powered by
Flask
and
CodeMirror
Source:
struct B {}; struct D1 :public B {}; struct DD1 : public D1 {}; struct DD2 : public D1 {}; struct D2 :public B {}; struct DD3 : public D2 {}; struct DD4 : public D2 {}; //abstract factory version 1 struct AbstractFactoryImpl { virtual D1* CreateD1() = 0; virtual D2* CreateD2() = 0; }; struct AbstractFactory : public AbstractFactoryImpl { virtual D1* CreateD1() { return new D1; }; virtual D2* CreateD2() { return new D2; }; }; #include<tuple> template<class ... Ts> struct ConcreteFactory :public AbstractFactory { using params = std::tuple<Ts...>; using T1 = typename std::tuple_element_t<0, params>; using T2 = typename std::tuple_element_t<1, params>; virtual D1* CreateD1()override { static_assert(std::is_base_of_v<D1, T1>); return new T1; }; virtual D2* CreateD2()override { static_assert(std::is_base_of_v<D2, T2>); return new T2; }; }; //abstract factory version 2 template<typename T> struct AbstractFactoryImpl_ { virtual T* Create() = 0; }; template<typename T> struct AbstractFactory_ :public AbstractFactoryImpl_<T> { virtual T* Create() override { return new T; } }; template<class ...Ts> struct ConcreteFactory_ : public AbstractFactory_<Ts>... { using params = std::tuple<Ts...>; using T1 = typename std::tuple_element_t<0, params>; using T2 = typename std::tuple_element_t<1, params>; template<class T> T* Create() { if constexpr (std::is_base_of_v<T, T1>)return AbstractFactory_<T1>::Create(); else if constexpr (std::is_base_of_v<T, T2>)return AbstractFactory_<T2>::Create(); } }; int main() { //version 1 AbstractFactory* pFactory; pFactory = new ConcreteFactory<DD1, DD3>; D1* pD1 = pFactory->CreateD1(); D2* pD2 = pFactory->CreateD2(); pFactory = new ConcreteFactory<DD2, DD4>; pD1 = pFactory->CreateD1(); pD2 = pFactory->CreateD2(); //version 2 //AbstractFactory* pFactory; -- can`t use because AbstractFactory in version 2 is template class. auto pFactory_1 = new ConcreteFactory_<DD1, DD3>; D1* pD1_ = pFactory_1->Create<D1>(); D2* pD2_ = pFactory_1->Create<D2>(); auto pFactory_ = new ConcreteFactory_<DD2, DD4>; pD1_ = pFactory_->Create<D1>(); pD2_ = pFactory_->Create<D2>(); //TYPE* pFactory_ = new ConcreteFactory_<DD1, DD3>; //D1* pD1_ = pFactory_->Create<D1>(); //D2* pD2_ = pFactory_->Create<D2>(); //auto pFactory_ = new ConcreteFactory_<DD2, DD4>; //pD1_ = pFactory_->Create<D1>(); //pD2_ = pFactory_->Create<D2>(); return 1; };
Insight:
Console: