Du bist nicht angemeldet.

Werbeanzeige

Julién

Alter Hase

  • »Julién« ist der Autor dieses Themas

Beiträge: 723

Wohnort: Bayreuth

Beruf: Student | Hilfswissenschaftler in der Robotik

  • Private Nachricht senden

1

16.06.2016, 18:41

C++ | Wie rufe ich einen Konstruktor mit Templates auf?

Hi,
ich habe ein Problem, wo ich mir nicht so ganz sicher bin, wie ich das lösen kann.
In meinem Projekt befindet sich folgende Klasse:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
template<typename... params>
class Callback{
    //...
    template<void (*Function)(params...)>
    Callback(){
        // Pointer speichern
    }
}


Wie rufe ich nun den Konstruktor auf?
Folgendes habe ich probiert, funktioniert aber nicht:

C-/C++-Quelltext

1
2
3
void foo(int i){...};

Callback<int> cb<foo>;


Der Compiler beschwert sich über ein fehlendes Semikolon,
jedoch kommt diese Beschwerde nur, wenn ich den Konstruktor versuche aufzurufen.

Gibt's da eine Lösung?

LG Julien
I write my own game engines because if I'm going to live in buggy crappy filth, I want it to me my own - Ron Gilbert

BlueCobold

Community-Fossil

Beiträge: 10 859

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

16.06.2016, 18:53

Gibt's einen Grund nicht std::function zu benutzen?

Und ja, da fehlt ein Semikolon nach der Klassen-Deklaration.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Julién

Alter Hase

  • »Julién« ist der Autor dieses Themas

Beiträge: 723

Wohnort: Bayreuth

Beruf: Student | Hilfswissenschaftler in der Robotik

  • Private Nachricht senden

3

16.06.2016, 18:59

Das Semikolon fehlt nur hier in diesem Beispiel.

Warum mache ich selber eine Implementierung?
Einerseits wollte ich wissen, was 'under-the-hood' passiert,
andererseits soll 'std::function' extra Speicher allozieren.
Meine Implementierung tut das nicht.
I write my own game engines because if I'm going to live in buggy crappy filth, I want it to me my own - Ron Gilbert

BlueCobold

Community-Fossil

Beiträge: 10 859

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

16.06.2016, 19:04

Na ja, du legst die Parameter da ja auch nirgendwo ab, is klar, dass Du da keinen separaten Speicher brauchst... Von Capturing mal ganz zu schweigen, wie etwa bei Lambdas öfter mal üblich. Die musst Du irgendwo hinlegen. Wahlweise natürlich den this-Pointer, falls Du nicht nur statische Funktionen, sondern Methoden referenzieren willst.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Schorsch

Supermoderator

Beiträge: 5 206

Wohnort: Wickede

Beruf: Student

  • Private Nachricht senden

5

16.06.2016, 19:04

Läuft es denn ohne Template?
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

BlueCobold

Community-Fossil

Beiträge: 10 859

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

16.06.2016, 19:07

Ich finde Zeile 3 im zweiten Code übrigens syntaktisch "spannend"...
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Julién

Alter Hase

  • »Julién« ist der Autor dieses Themas

Beiträge: 723

Wohnort: Bayreuth

Beruf: Student | Hilfswissenschaftler in der Robotik

  • Private Nachricht senden

7

16.06.2016, 19:10

Das ist ja die Frage. Ich stehe gerade voll auf dem Draht.
I write my own game engines because if I'm going to live in buggy crappy filth, I want it to me my own - Ron Gilbert

BlueCobold

Community-Fossil

Beiträge: 10 859

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

8

16.06.2016, 19:20

OK, was stört Dich an folgendem:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
template<typename... params>
class Callback{
    //...
public:
    Callback(void (*f)(params...)){
        // Pointer speichern
    }
};

Callback<int> cb(foo);
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

9

16.06.2016, 19:31

Du kannst einen solchen Konstruktor nicht ohne argument deduction aufrufen, weil es syntaktisch keinen unproblematischen Weg gibt, dem seine Argumente zu geben. Der einzige Weg wäre ein Konstrukt wie Foo<int>::Foo<Func>(), aber... :thumbdown: [zum Glück]
Was spricht dagegen, das Ganze der Klasse an sich zu geben, statt dem Konstruktor? Was spricht gegen BlueCobolds Lösung?

MfG
Check

Julién

Alter Hase

  • »Julién« ist der Autor dieses Themas

Beiträge: 723

Wohnort: Bayreuth

Beruf: Student | Hilfswissenschaftler in der Robotik

  • Private Nachricht senden

10

16.06.2016, 19:38

Intern werden bei mir die Funktionen als Templates erwartet, damit ich für Funktionen und Methoden
die gleiche Signatur habe.

Demnach wollte ich folgendes Probieren:

C-/C++-Quelltext

1
2
3
4
5
                template<void (*Function)(params...)>
                Callback()
                : instance{nullptr}
                , func{&functionStub<Function>}
                {}


@Checkmateing: Wie meinst du das mit 'das Ganze der Klasse an sich zu geben'?

EDIT: Hier mal wie ich das ganze implementiere:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
        template<typename... params>
        class Callback{
            private:
                using InstancePtr   = void*;
                using FuncPtr       = void(*)(InstancePtr, params...);

                FuncPtr     func;       // Function to be called.
                InstancePtr instance;   // Instance to operate on.

                template<void (*Function)(params...)>
                static inline void functionStub(InstancePtr, params... param){
                    (Function)(param...);
                }
            
                template<class T, void(T::*Function)(params...)>
                static inline void methodStub(InstancePtr instance, params... param){
                    (static_cast<T*>(instance)->*Function)(param...);
                }

            public:

                Callback() 
                : func(nullptr)
                , instance(nullptr)
                {}
 
                // Mein 'Versuch' es in einen Konstruktor zu packen.
                template<void (*Function)(params...)>
                Callback()
                : instance{nullptr}
                , func{&functionStub<Function>}
                {}

                template<void (*Function)(params...)>
                void bind(){
                    func = &functionStub<Function>;
                }

                template<class T, void(T::*Function)(params...)>
                void bind(T* instance){
                    this->instance = instance;
                    func = &methodStub<T, Function>;
                }

                void operator()(params... param){
                    func(instance, std::forward<params>(param)...);
                }
        };


Mein Ziel des ganzen war es jetzt die 'bind'-Funktionen durch einen entsprechenden Konstruktor zu ersetzen,
da ich verhindern will, dass jemand einen uninitialisierten Callback aufruft.

EDIT: Die einzige Möglichkeit, die mir jetzt einfällt, ist die Erstellung einer Factorymethode.
I write my own game engines because if I'm going to live in buggy crappy filth, I want it to me my own - Ron Gilbert

Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von »Julién« (16.06.2016, 20:13)


Werbeanzeige