C++ partial member function - hjälp!

Permalänk
Medlem

C++ partial member function - hjälp!

Tja!
Jag har följande programkod och undrar hur jag definerar funktionerna som ska användas när T = sa eller sb? Jag har googlat runt en del men inte hittat något som har hjälpt mig.

EDIT: Löst!

#include <iostream> #include <vector> #include <typeinfo> struct sa { //Massa skumma ctors }; struct sb { //Massa skumma ctors }; class cfactory { //Här hamnar de beronde på typ std::vector<sa*> vSA_; std::vector<sb*> vSB_; public: //Skapar object av typen T och med argumenten A. //Returnerar nullptr ifall T inte finns i "factory"... template <typename T, typename ...A> T *create(A&&... args); }; //Standard för de som inte finns template <typename T, typename ...A> T *cfactory::create(A&&... args) { std::cout << "cfactory::create: T = " << typeid(T).name() << std::endl; return (T*)nullptr; } //Den här och nästa funktion undrar jag hur man definerar korrekt. //För "sa" template <typename ...A> sa *cfactory::create(A&&... args) { std::cout << "cfactory::create: T = " << typeid(T).name() << std::endl; sa *s = new sa(std::forward<A>(args)...); vSA_.push_back( s ); return s; } //För "sb" template <typename ...A> sb *cfactory::create(A&&... args) { std::cout << "cfactory::create: T = " << typeid(T).name() << std::endl; sb *s = new sb(std::forward<A>(args)...); vSB_.push_back( s ); return s; } int main() { cfactory factory; factory.create<int>(5); //Anropar standrad funktionen och det fungerar solklart! //Så vill jag få till någon i den här stilen sb *sb_ = factory.create<sb>(/* BLa bla bla osv m.m.*/); sa *sa_ = factory.create<sa>(/* BLa bla bla osv m.m.*/); return -1; };

Här är min slutgiltiga lösning.

#include <iostream> #include <string> #include <vector> #include <typeinfo> struct sa { //Massa skumma ctors }; struct sb { std::string a_; int b_; //Massa skumma ctors sb(const std::string& a) : a_(a){} sb(int b) : b_(b){} sb(const std::string& a, int b) : a_(a), b_(b){} }; class cfactory { std::vector<sa*> vSA_; std::vector<sb*> vSB_; public: void out() { for(auto p:vSB_) std::cout << p->a_ <<" " << p->b_ << std::endl; } template <typename T> T* create_obj(T *obj); template <typename T, typename ...A> T* create(A&&... args); }; template <typename T, typename ...A> T* cfactory::create(A&&... args) { return create_obj( new T(std::forward<A>(args)... )); } template <> sa* cfactory::create_obj(sa *obj) { vSA_.push_back(obj); std::cout << "Fungerar för sa! " << std::endl; return obj; } template <> sb* cfactory::create_obj(sb *obj) { vSB_.push_back(obj); std::cout << "Fungerar för sb! " << std::endl; return obj; } int main() { cfactory factory; //factory.create<int>(5); //Så vill jag få till någon i den här stilen sb *sb_1 = factory.create<sb>(12); sb *sb_2 = factory.create<sb>("hej", 42); sb *sb_3 = factory.create<sb>("tack för hjälpen!"); sa *sa_ = factory.create<sa>(/* BLa bla bla osv m.m.*/); factory.out(); return -1; };

Visa signatur

Intel pentium 3.0ghz @ 3.5ghz
ATI Radeon HD 3850
alltså en skräpdator...

Permalänk
Medlem
Skrivet av andenswe:

Tja!
Jag har följande programkod och undrar hur jag definerar funktionerna som ska användas när T = sa eller sb? Jag har googlat runt en del men inte hittat något som har hjälpt mig.

Jag gissar att du vill göra Template Specialization

ett kort exempel är

#include <iostream> struct A { int a; }; class F { public: F(){}; template<typename T> void run(T& iObj); ~F(){}; }; template<typename T> void F::run(T& iObj) { std::cout << "in general"<< std::endl; }; template<> void F::run(A& iObj) { iObj.a = 10; }; void main() { A obj; F funcObj; int val =1; obj.a=val; funcObj.run(val); std::cout << "value before func " << obj.a << std::endl; funcObj.run(obj); std::cout << "value after func " << obj.a << std::endl; }

Om inte mitt exempel var bra nog kan du kan läsa mer på
http://www.cprogramming.com/tutorial/template_specialization....

Lycka till!

Permalänk
Medlem

Ja, det är det jag vill göra. För i övrigt så har jag lyckats få till partial member Specialization i tidigare fall men när jag försöker ersätta typen T med något annat så fungerar det inte. Jag kan inte fårstå varför dock :/
För den som undrar använder jag g++ 4.8 och kompilerar med -std=c++0x

Visa signatur

Intel pentium 3.0ghz @ 3.5ghz
ATI Radeon HD 3850
alltså en skräpdator...

Permalänk
Medlem
Skrivet av MrGorgar:

Lämnade du template argumentet tomt på den specialiserade funktionen?

template<> //endast på den specialiserade ska det vara tomt void F::run(A& iObj) { iObj.a = 10; };

Har provat det också utan resultat. Men eftersom att argumenten inte är specialiserade så ska "A" i mitt fall vara innanför <> ifall jag inte är helt ut och cyklar?

Visa signatur

Intel pentium 3.0ghz @ 3.5ghz
ATI Radeon HD 3850
alltså en skräpdator...

Permalänk
Medlem
Skrivet av andenswe:

Har provat det också utan resultat. Men eftersom att argumenten inte är specialiserade så ska "A" i mitt fall vara innanför <> ifall jag inte är helt ut och cyklar?

Hoppades jag skulle hinna ta bort den komentaren innan du läste då jag såg att du redan försökt detta fast med partial specialication.

När jag kollade igenom din kod mer ser jag att du försöker att templata endast return argumentet och det går inte

template <class T> T func(int x) { //... }

Ett alternativ är

template <class T> T* func(T val) { //... }

Permalänk
Medlem

om du vill använda det senaste c++11 så kan du använda auto decltype vilket ger en försenad utvädering av retur argumentet.
Bara använt det några få gånger så jag ger inget eget exempel men du kan läsa ett bra exempel på
http://kjellkod.wordpress.com/2014/04/30/c11-template-tricks-...

Permalänk
Medlem

Om du använder dig av lite hjälpklasser så går det ganska smidigt:

#include <iostream> #include <vector> #include <typeinfo> struct sa { //Massa skumma ctors }; struct sb { //Massa skumma ctors }; //Forward-declaration av cfactory_helper så att den kan bli friend i cfactory template<typename T> class cfactory_helper; class cfactory { private: //Här hamnar de beronde på typ std::vector<sa*> vSA_; std::vector<sb*> vSB_; public: template <typename T, typename ...A> T *create(A&&... args); template<typename Z> friend class cfactory_helper; }; //Standard för de som inte finns template<typename T> class cfactory_helper { public: template <typename ...A> static T* create(cfactory *cf, A&&... args) { std::cout << "cfactory::create: T = " << typeid(T).name() << std::endl; return (T*)nullptr; } }; //För "sa" template<> class cfactory_helper<sa> { public: template <typename ...A> static sa* create(cfactory *cf, A&&... args) { std::cout << "cfactory::create<sa>: T = " << typeid(sa).name() << std::endl; sa *s = new sa(std::forward<A>(args)...); cf->vSA_.push_back( s ); return s; } }; //För "sb" template<> class cfactory_helper<sb> { public: template <typename ...A> static sb* create(cfactory *cf, A&&... args) { std::cout << "cfactory::create<sb>: T = " << typeid(sb).name() << std::endl; sb *s = new sb(std::forward<A>(args)...); cf->vSB_.push_back( s ); return s; } }; template <typename T, typename ...A> T *cfactory::create(A&&... args) { return cfactory_helper<T>::create(this,args...); } int main() { cfactory factory; factory.create<int>(5); //Anropar standrad funktionen och det fungerar solklart! //Så vill jag få till någon i den här stilen sb *sb_ = factory.create<sb>(/* BLa bla bla osv m.m.*/); sa *sa_ = factory.create<sa>(/* BLa bla bla osv m.m.*/); return -1; };

[$ /tmp/foo] ./a.out cfactory::create: T = i cfactory::create<sb>: T = 2sb cfactory::create<sa>: T = 2sa

Visa signatur

The difference between stupidity and genius - the latter has limits

Permalänk
Medlem

Tja fick till det tillslut och tack för hjälpen!
Hur jag gick till väga skriver jag i mitt första inlägg

Visa signatur

Intel pentium 3.0ghz @ 3.5ghz
ATI Radeon HD 3850
alltså en skräpdator...