#include <iostream>
#include <string>
#include <vector>
using namespace std;
class sai
{
public:
virtual void unknown03()=0;
};
class saiA:public sai
{
public:
virtual void unknown03() { cout<<"A.unknown03()"<<endl; }
};
class saiB:public sai
{
public:
virtual void unknown03() { cout<<"B.unknown03()"<<endl; }
};
sai *find_interface(const char *dll,const char *name)
{
cout<<dll<<' '<<name<<endl;
if(dll==string("abc")) return new saiA();
else if(dll==string("ghi")) return new saiB();
return nullptr;
}
class InterfaceBase
{
public:
virtual sai *get()=0;
sai *operator->() { return get(); }
};
template<const char *dll,const char *name> class Interface: public InterfaceBase
{
public:
virtual sai *get()
{
static sai *intf=find_interface(dll,name);
return intf;
}
};
constexpr char abc[]="abc";
constexpr char def[]="def";
constexpr char ghi[]="ghi";
constexpr char jkl[]="jkl";
int main()
{
vector<InterfaceBase*> IntList;
IntList.push_back(new Interface<abc,def>());
IntList.push_back(new Interface<ghi,jkl>());
for(auto intf:IntList) (*intf)->unknown03();
for(auto intf:IntList) (*intf)->unknown03();
for(auto intf:IntList) (*intf)->unknown03();
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8dmVjdG9yPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKY2xhc3Mgc2FpCnsKICBwdWJsaWM6CiAgdmlydHVhbCB2b2lkIHVua25vd24wMygpPTA7Cn07CgpjbGFzcyBzYWlBOnB1YmxpYyBzYWkKewogIHB1YmxpYzoKICB2aXJ0dWFsIHZvaWQgdW5rbm93bjAzKCkgeyBjb3V0PDwiQS51bmtub3duMDMoKSI8PGVuZGw7IH0KfTsKCmNsYXNzIHNhaUI6cHVibGljIHNhaQp7CiAgcHVibGljOgogIHZpcnR1YWwgdm9pZCB1bmtub3duMDMoKSB7IGNvdXQ8PCJCLnVua25vd24wMygpIjw8ZW5kbDsgfQp9OwoKc2FpICpmaW5kX2ludGVyZmFjZShjb25zdCBjaGFyICpkbGwsY29uc3QgY2hhciAqbmFtZSkKewoJY291dDw8ZGxsPDwnICc8PG5hbWU8PGVuZGw7CglpZihkbGw9PXN0cmluZygiYWJjIikpIHJldHVybiBuZXcgc2FpQSgpOwoJZWxzZSBpZihkbGw9PXN0cmluZygiZ2hpIikpIHJldHVybiBuZXcgc2FpQigpOwoJcmV0dXJuIG51bGxwdHI7Cn0KCmNsYXNzIEludGVyZmFjZUJhc2UKewoJcHVibGljOgoJdmlydHVhbCBzYWkgKmdldCgpPTA7CglzYWkgKm9wZXJhdG9yLT4oKSB7IHJldHVybiBnZXQoKTsgfQp9OwoKdGVtcGxhdGU8Y29uc3QgY2hhciAqZGxsLGNvbnN0IGNoYXIgKm5hbWU+IGNsYXNzIEludGVyZmFjZTogcHVibGljIEludGVyZmFjZUJhc2UKewogICAgcHVibGljOgoJdmlydHVhbCBzYWkgKmdldCgpCgl7CgkJc3RhdGljIHNhaSAqaW50Zj1maW5kX2ludGVyZmFjZShkbGwsbmFtZSk7CgkgCXJldHVybiBpbnRmOyAKCX0KfTsKCmNvbnN0ZXhwciBjaGFyIGFiY1tdPSJhYmMiOwpjb25zdGV4cHIgY2hhciBkZWZbXT0iZGVmIjsKY29uc3RleHByIGNoYXIgZ2hpW109ImdoaSI7CmNvbnN0ZXhwciBjaGFyIGprbFtdPSJqa2wiOwoKaW50IG1haW4oKQp7Cgl2ZWN0b3I8SW50ZXJmYWNlQmFzZSo+IEludExpc3Q7CglJbnRMaXN0LnB1c2hfYmFjayhuZXcgSW50ZXJmYWNlPGFiYyxkZWY+KCkpOwoJSW50TGlzdC5wdXNoX2JhY2sobmV3IEludGVyZmFjZTxnaGksamtsPigpKTsKCWZvcihhdXRvIGludGY6SW50TGlzdCkgKCppbnRmKS0+dW5rbm93bjAzKCk7Cglmb3IoYXV0byBpbnRmOkludExpc3QpICgqaW50ZiktPnVua25vd24wMygpOwoJZm9yKGF1dG8gaW50ZjpJbnRMaXN0KSAoKmludGYpLT51bmtub3duMDMoKTsKICAgIHJldHVybiAwOwp9Cg==