Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

p0llux

Treue Seele

  • »p0llux« ist der Autor dieses Themas

Beiträge: 101

Wohnort: Aachen

Beruf: HiWi (theo. Inf.)

  • Private Nachricht senden

1

17.02.2008, 13:52

[C++] Funktionszeiger als Templateargument

Hallo zusammen,

der Titel sagt eigentlich schon alles. Ich möchte eine parametrisierte Klasse schreiben, bei der ich eine nullstellige Funktion angeben, die nen int ausgibt. Meine Idee war bisher:

Quellcode

1
2
3
4
template <unsigned long (*Foo)()>
class Bar
{
};


Ich habe auch eine entsprechende Funktion. Bei der Instanzierung beschwert sich der G++ Compiler allerdings darüber, dass die Verlinkung von der Funktion nicht extern wäre.

Quellcode

1
main.c:12: error: 'simplis::mersenne::random' is not a valid template argument for type 'long unsigned int (*)()' because function 'long unsigned int simplis::mersenne::random()' has not external linkage


Kann mir da jemand helfen?

Anbei noch die Deklaration/Definition der entsprechenden Funktion:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
namespace simplis
{
    
    namespace mersenne
    {

        //! Retrieve a random integer value.
        static unsigned long random();

    }
    
}

static unsigned long simplis::mersenne::random() { /* ... */ }


Michael.

2

17.02.2008, 13:55

int != unsigned long
Mein Projekt: Rise of the Sylvan

p0llux

Treue Seele

  • »p0llux« ist der Autor dieses Themas

Beiträge: 101

Wohnort: Aachen

Beruf: HiWi (theo. Inf.)

  • Private Nachricht senden

3

17.02.2008, 13:59

Zitat von »"Crash"«

int != unsigned long


Ja. Das ist mir irgendwie klar. Allerdings dient das erste Beispiel (wie man vielleicht auch an den Namen erkennt) zur einfachen Darstellung des Problems. Genau genommen stecken da auch noch drei andere Templateparameter drin, etc. Der Templateparameter passt also. Ich habs aber mal im OP geändert.

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

4

17.02.2008, 14:02

Pass die Signatur an, lass das static weg. Dann sollte es funktionieren.
@D13_Dreinig

p0llux

Treue Seele

  • »p0llux« ist der Autor dieses Themas

Beiträge: 101

Wohnort: Aachen

Beruf: HiWi (theo. Inf.)

  • Private Nachricht senden

5

17.02.2008, 14:03

Ah, okay das static war's. Dankesehr :)

6

17.02.2008, 19:45

Guck dir mal das Konzept des Standards da an ... vllt. mal nen blick auf std::find_if(z.B.), std::mem_fun, std::mem_fun_ref und std::ptr_fun werfen ;)
Devil Entertainment :: Your education is our inspiration
Der Spieleprogrammierer :: Community Magazin
Merlin - A Legend awakes :: You are a dedicated C++ (DirectX) programmer and you have ability to work in a team? Contact us!
Siedler II.5 RttR :: The old settlers-style is comming back!

Also known as (D)Evil

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

7

18.02.2008, 07:03

Genau, warum so umständlich... ;)

Hier muss man auch aufpassen, weil das evtl. gar nicht das ist, was du haben willst. Einen Functor (eine Klasse, die "operator ()" definiert) könntest du hier nämlich nicht benutzen.

So wie du es schreibst, ist das kein Typen-Templateparameter, sondern etwas wie ein int. Und bei diesen Konstanten gibt es einige Einschränkungen, wie z.B. "external linkage." (ich muss mir dazu mal eine verständliche Definition raussuchen, das ist nicht besonders intuitiv)

C-/C++-Quelltext

1
2
3
4
5
6
7
template<typename Func_t>
class Bar
{
  Bar (const Func_t& func) : func_ (func) { }
private:
  Func_t func_;
};


So würde es auch gehen, und du bist flexibler, denn es gehen auch Functoren, so dass du in diesen einen Status haben kannst -- geht mit direkten Funktionszeigern ohne Objekt nicht so gut -- und du bist nicht so sehr auf den Ergebnistyp festgelegt, solange dieser intern in den richtigen Typ konvertiert werden kann -- das kann allerdings auch ein Nachteil sein.

Beim Static bist du vermutlich darauf reingefallen, dass es sich bei deinem "random" gar nicht um eine Member-Methode handelt. Das ist nämlich auch nicht intuitiv in C++... static an einem Member bedeutet, dass der Member auch ohne Objekt funktioniert und überall sichtbar ist, wo dies auch für die Klasse gilt, static an einer globalen Funktion bedeutet, dass nur in der aktuellen "Compilier-Einheit" (dem .o File) sichtbar ist. Im letzteren Fall hat sie dann offensichtlich nicht die Eigenschaft "external linkage." Versuch mal einen statischen Non-Member an anderer Stelle mit "extern" wieder sichtbar zu machen. Spätestens der Linker wird dir das einfach um die Ohren hauen :)
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

8

18.02.2008, 08:03

Zitat von »"rklaffehn"«


Beim Static bist du vermutlich darauf reingefallen, dass es sich bei deinem "random" gar nicht um eine Member-Methode handelt. Das ist nämlich auch nicht intuitiv in C++... static an einem Member bedeutet, dass der Member auch ohne Objekt funktioniert und überall sichtbar ist, wo dies auch für die Klasse gilt, static an einer globalen Funktion bedeutet, dass nur in der aktuellen "Compilier-Einheit" (dem .o File) sichtbar ist. Im letzteren Fall hat sie dann offensichtlich nicht die Eigenschaft "external linkage." Versuch mal einen statischen Non-Member an anderer Stelle mit "extern" wieder sichtbar zu machen. Spätestens der Linker wird dir das einfach um die Ohren hauen :)


Er wollte ja garkeine Member-Methode haben.
@D13_Dreinig

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

9

18.02.2008, 12:00

Ich wollte eigentlich nur nochmal rausstellen, dass es da immer leicht Verwirrungen gibt. :D

Denn: wäre es eine Mitgliedsmethode gewesen, hätte er für diese Anwendung ein static gebraucht. Wenn es keine sein soll, darf sie für diese Anwendung nicht static sein.
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

p0llux

Treue Seele

  • »p0llux« ist der Autor dieses Themas

Beiträge: 101

Wohnort: Aachen

Beruf: HiWi (theo. Inf.)

  • Private Nachricht senden

10

19.02.2008, 13:14

Zitat von »"rklaffehn"«

Ich wollte eigentlich nur nochmal rausstellen, dass es da immer leicht Verwirrungen gibt. :D

Denn: wäre es eine Mitgliedsmethode gewesen, hätte er für diese Anwendung ein static gebraucht. Wenn es keine sein soll, darf sie für diese Anwendung nicht static sein.


Ja. Das wusste ich tatsächlich nicht, aber durch Fehler wird man klug und schläft nicht so viel ;)

Werbeanzeige