2016-03-30 5 views
0

Im base.h:Übergeben Sie die Template-Klasse zu einer Funktion

template <typename T, typename T2> class Base 
{ 
public: 
    virtual int Foo(T param1) = 0; 
    virtual int Bar(T param1, T2 param2) = 0; 
}; 

Im derived1.h:

template <typename T, typename T2> class Derived1 : public Base<T, T2> 
{ 
public: 
    virtual int Foo(T param1); 
    virtual int Bar(T param1, T2 param2); 
}; 

Im derived2.h:

template <typename T, typename T2> class Derived2 : public Base<T, T2> 
{ 
public: 
    virtual int Foo(T param1); 
    virtual int Bar(T param1, T2 param2); 
}; 

In myfile.cpp:

extern "C" template<typename T, typename T2> Base<T, T2> *my_func(template<typename T, typename T2> Base<T, T2> *param) 
{ 
    if(<cond1>) 
     param<char, char> = new Derived1<char, char>(); 
    if(<cond2>) 
     param<SQLWCHAR, SQLWCHAR> = new Derived2<SQLWCHAR, SQLWCHAR>(); 
    return param<T, T1>; 
} 

Wird dieser Code sowohl in MSVC 2010 als auch in gcc kompiliert?

Ich hatte schon Probleme mit Compiler Schalten, zuerst so fragen wollte es, bevor man ...

auch: Ich die Funktion templatized werden nicht wollen. Ich möchte das Template-Objekt übergeben und von der Funktion zurückgegeben werden.

Vielen Dank.

[EDIT]

ich gerade nach Hause kam und versuchte:

extern "C" __declspec(dllexport) template<typename T, typename T2> Base<T, T2> *my_func(Base<T, T2> *param) 

und bekam dies:

warning C4091: '__declspec(dllexport)' : ignored on left of 'int' when no variable is declared 
error C2143: syntax error : missing ';' before ''template<'' 

Wie mache ich es? Die Funktion muss exportiert werden und sollte daher eine C-Verknüpfung haben.

Der andere Weg ist, die Funktion als C++ zu definieren und seinen Symbolnamen aus der dll/so zu holen, was schmerzhaft ist.

[/ EDIT]

[EDIT2}

Was ich im Sinn hatte tatsächlich ist, so etwas zu schreiben:

class CMainFrame 
{ 
private: 
    template<typename T, typename T2> Base<T, T2> *m_pBase; 
public: 
    CMainFrame(); 
    ~CMainFrame(); 
    int CallFunc(); 
}; 

CMainFrame::CMainFrame() {} 

CMainFrame::~CMainFrame() 
{ 
    delete m_pBase; 
} 

int CMainFrame::CallFunc() 
{ 
    template<typename T, typename T2> Base<T, T2> *base = NULL; 
    m_pBase<T, T2> = my_func(base); 
} 

[/ EDIT 2]

+2

Sieht aus wie es eklatante Syntaxfehler enthält, so die Antwort von "Nein." –

+0

@UlrichEckhardt, welchen Compiler hast du benutzt? – Igor

+0

Keine, daher sagte ich "sieht aus wie". Funktioniert dieser Code für Sie? Beachten Sie, dass Vorlagen bei der Instanziierung nur vollständig Syntax-geprüft und kompiliert werden! –

Antwort

0
template<typename T, typename T2> 
Base<T, T2> *my_func(Base<T, T2> *param) 
{ 
    param = new Derived<T, T2>(); 
    return param; 
} 

oder

Base<char, char> *my_func(Base<char, char> *param) 
{ 
    param = new Derived<char, char>(); 
    return param; 
} 

Beachten Sie, dass es keinen Grund zu sein scheint für param- ein Parameter sein, wenn es nur ist, als eine lokale Variable verwendet werden, so würde dies besser funktionieren:

template<typename T, typename T2> 
Base<T, T2> *my_func() 
{ 
    Base<T, T2> *param = new Derived<T, T2>(); 
    return param; 
} 

oder

Base<char, char> *my_func() 
{ 
    Base<char, char>* param = new Derived<char, char>(); 
    return param; 
} 

Basierend auf OPs Klarstellung: versuchen Sie dies. Wenn Sie wirklich param übergeben müssen, können Sie es als Base<T,T2>* param deklarieren - aber ich glaube nicht, dass Sie das müssen.Ich bin auch nicht sicher, warum Sie brauchen param von Typ Base<T,T2> zu sein, denn nachdem es kompiliert ist, ist es gehen zu einigen tatsächlichen Typ, oder Base<SQWLCHAR,SQWLCHAR> oder was hast du. Aber wie auch immer, hier ist es.

template<typename T, typename T2> 
Base<T, T2> *my_func() 
{ 
    Base<T, T2>* param; 

    if(<cond1>) 
     param = new Derived1<char, char>(); 
    else if(<cond2>) 
     param = new Derived2<SQLWCHAR, SQLWCHAR>(); 
    else 
     param = ??whatever it should be if neither condition applies??; 
    return param; 
} 

OK, bezogen auf die nächsten Klärung, das sieht aus wie was versucht hat wird:

class Database //an interface: no data, function prototypes only 
{ 
public: 
    virtual QueryResultType query (const char* queryText) = 0; 
    ... 
}; 

class SQLiteDatabase: public Database 
{ 
public: 
    QueryResultType query (const char* queryText); 
    //this function has a body, and deals with queries the SQLite way 
}; 

... 

Database* myDatabase = new SQLiteDatabase(); 
+0

Ich muss tatsächlich in der Templatised-Klasse übergeben und innerhalb der Funktion das tatsächliche Objekt mit tatsächlichen Parametern instanziieren. Also muss ich übergeben, in der Funktion ein passendes Objekt mit instanziieren und als zurückgeben. Ich habe paarweise abgeleitete Klassen - wobei einige mit char und einige mit SQLWCHAR arbeiten.Also muss ich eine Vorlage übergeben, ein Objekt mit dem tatsächlichen Typ basierend auf einer Bedingung instanziieren und dann das Vorlagenobjekt zurückgeben. Außerdem glaube ich, dass die letzte 2 Version nicht funktionieren würde - ich werde eine lokale Variable zurückgeben, die außerhalb des Gültigkeitsbereichs liegt. – Igor

+0

Bitte beachten Sie auch den bearbeiteten Code zur Verdeutlichung. Das ist es, was ich im Sinn habe. Dann hat der Anrufer nur den Zeiger "Base ". – Igor

+0

Über den Geltungsbereich hinaus: Sie geben param zurück, das ein Zeiger ist. Param geht nicht mehr in den Geltungsbereich, aber was darauf hinweist, ist es nicht, so dass es immer noch da sein wird, sobald du zurückkehrst. Dies ist eine herkömmliche Art, einen dynamisch zugewiesenen Wert zurückzugeben. Seien Sie sicher und rufen Sie 'delete' darauf, wenn Sie damit fertig sind! –

Verwandte Themen