Forum: Mikrocontroller und Digitale Elektronik Funktion überladen für const Arg (für alternative Algo)


von Phlupp (Gast)


Lesenswert?

Hallo,
also ich dachte ja,
1
void fkt(const uint8_t);
2
void fkt(uint8_t);
wäre möglich, um z.B. zwischen fkt(x) und fkt(5) zu unterscheiden. So 
könnte man einen optimierten Algorithmus für den fkt(5)-Fall schreiben.
Aber Compiler sagt nein.
Kann mir jemand erklären, warum das nicht erlaubt ist? Wo würde das zu 
Problemen führen?
Zur not könnte man das (in c++) mit templates lösen. Aber weiß trotzdem 
wer, wie man das mit echter Überladung macht?

Danke schon mal,
Phlupp

von Nico W. (nico_w)


Lesenswert?

Dein const uint8_t sagt nur das du einen uint8_t der Funktion übergibst 
der in der Funktion nicht verändert werden darf/kann.

Es heißt nicht, dass die Funktion einen const uint8_t erwartet.

von PPB (Gast)


Lesenswert?

Du kannst nicht zweimal die selbe Funktion mit unterschiedlichen 
Parametern haben.

Dafür baut man sich wrapper oder verbiegt Funktionszeiger.

von vn nn (Gast)


Lesenswert?


von vn nn (Gast)


Lesenswert?

PPB schrieb:
> Du kannst nicht zweimal die selbe Funktion mit unterschiedlichen
> Parametern haben.

https://en.cppreference.com/book/intro/function_overloading

von PPB (Gast)


Lesenswert?

vn nn schrieb:
> PPB schrieb:
>> Du kannst nicht zweimal die selbe Funktion mit unterschiedlichen
>> Parametern haben.
>
> https://en.cppreference.com/book/intro/function_overloading

Das ist C++ und nicht C.

von Phlupp (Gast)


Lesenswert?

>Es heißt nicht, dass die Funktion einen const uint8_t erwartet.
Das meint auch der Compiler. Ich frage mich nur, warum. Wo wäre das 
Problem?

>Du möchtest constexpr:
"a parameter cannot be declared 'constexpr'"

..Und die komplette Funktion auch nicht, da es eigentlich eine
1
 fkt(T y, const uint8_t x)
ist.

von Nico W. (nico_w)


Lesenswert?

Lese einfach mal ein paar Infos zu const correctness.

Was erwartest du denn ansonsten?

von Rolf M. (rmagnus)


Lesenswert?

Phlupp schrieb:
> Kann mir jemand erklären, warum das nicht erlaubt ist?

Es ergibt sich einfach daraus, dass Parameter per Kopie übergeben 
werden. Wenn du eine Funktion hast, wie

> void fkt(const uint8_t);

dann wird das übergebene Argument in den Parameter kopiert. Der ist dann 
im Prinzip quasi eine lokale Variable, die vom Aufrufer initialisiert 
wurde. Ob die dann innerhalb der Funktion const ist oder nicht, ist aber 
dem Aufrufer egal.
Wenn du jetzt keine Überladungen hast, sondern nur diese eine Funktion, 
erwartest du dann, dass du die nur mit Konstanten als Argument aufrufen 
kannst?

PPB schrieb:
> Das ist C++ und nicht C.

Hat ja auch keiner behauptet, dass das C sei.

von Phlupp (Gast)


Lesenswert?

>Was erwartest du denn ansonsten?
..dass "const int" ein anderer typ als "int" ist und "5" konstanter als 
"a".
Was spräche dagegen?

von Phlupp (Gast)


Lesenswert?

Hm, ich habe es jetzt mit
1
fkt1(T y, uint8_t & x);
2
fkt2(T y, const uint8_t & x);
3
fkt2b(T y, uint8_t && x);
4
fkt2c(T y, const uint8_t && x);
5
fkt3<x>(T y);
probiert.
2(a), 2b und 2c sind identisch. (Was ich bei b und c genau mache, weiß 
ich ehrlich gesagt nicht genau..)
Es scheint aber so, als wäre fkt3() noch immer am besten optimierbar vom 
compiler.
Warum?
Gibt es denn keine Möglichkeit, eine Funktion-Überladung (mit 2 'echten' 
Args) zu erhalten, die sich wie ein Template verhält, was das angeht?!

Jetzt, da
1
fkt1(T y, uint8_t & x);
2
fkt2(T y, const uint8_t & x);
funktioniert, frage ich mich eigentlich um so mehr, warum
1
fkt1(T y, uint8_t x);
2
fkt2(T y, const uint8_t x);
nicht funktioniert, obwohl es dafür keine Notwendigkeit zu geben 
scheint.

...denn im asm wird x eh nicht unterschiedlich behandelt, egal ob "&" 
oder nicht..

von M.K. B. (mkbit)


Lesenswert?

Phlupp schrieb:
> Jetzt, da fkt1(T y, uint8_t & x);
> fkt2(T y, const uint8_t & x);
>
> funktioniert, frage ich mich eigentlich um so mehr, warumfkt1(T y,
> uint8_t x);
> fkt2(T y, const uint8_t x);
>
> nicht funktioniert, obwohl es dafür keine Notwendigkeit zu geben
> scheint.

Das hat rmagnus schon gut erklärt. Der Unterschied bei der ersten 
Funktion ist, dass man eine Referenz übergibt. Ist die Variable die man 
dabei übergibt konstant, dann kann man die nur als const& übergeben. Bei 
der Kopie ist const für den Aufrufer irrelevant. Wenn die beiden 
Funktionen etwas anderes tun sollen, warum gibt man denen dann nicht 
einfach unterschiedliche Namen?

Willst du über den Unterschied philosophieren oder hast du ein konkretes 
Problem?

von Phlupp (Gast)


Lesenswert?

Danke,
ich hatte die Hoffnung, es gäbe eine schöne Lösung.

>Wenn die beiden
>Funktionen etwas anderes tun sollen, warum gibt man denen dann nicht
>einfach unterschiedliche Namen?
Weil sie eigentlich das gleiche tun, nur auf unterschiedliche Weise, 
bzw. mit leicht unterschiedlichen Typen.
Deine Frage könnte man auch übersetzen mit:"Warum gibt es überhaupt 
Überladung?"

>Willst du über den Unterschied philosophieren oder hast du ein konkretes
>Problem?
Für das konkrete Problem, siehe Eingangspost. Philosophieren würde ich 
eher darüber, warum man/der Compiler nicht unterscheidet, obwohl er es 
könnte. Es spricht schließlich nichts dagegen, es auf die 'allgemeinere' 
Variante zurückzuführen, sollte nur eine existieren. So wie es jetzt 
ist, bin ich offenbar gezwungen auf Templates auszuweichen, was den von 
dir geforderten unterschiedlichen Namen schon recht nahe kommt (bzw. es 
genau genommen ist).

von M.K. B. (mkbit)


Lesenswert?

Phlupp schrieb:
> Deine Frage könnte man auch übersetzen mit:"Warum gibt es überhaupt
> Überladung?"

Für mich ist Überladung sinnvoll, wenn die gleiche logische Operation 
(Funktionsname) auf verschiedenen Datentypen ausgeführt werden kann, 
dazu aber unterschiedliche Implementierung nötig sind. Ob die in der 
Funktion verwendete Kopie const ist oder nicht ändert aber nichts am 
Typ.

Phlupp schrieb:
> Für das konkrete Problem, siehe Eingangspost.

Ich habe deinen Post gelesen.
Du hast ein Problem konstruiert, welches mir in der praktischen 
Anwendung von C++ noch nie begegnet ist. Deshalb habe ich nach einem 
konkreten Problem gefragt, dass du lösen möchtest. Vielleicht kannst du 
mal ein konkretes Beispiel posten, dann kann man dir vielleicht auch 
helfen.

: Bearbeitet durch User
von Vincent H. (vinci)


Lesenswert?

Working draft N4659 S.313

"Parameter declarations that differ only in the presence or absence of 
const and/or volatile are equivalent. That is, the const and volatile 
type-specifiers for each parameter type are ignored."

von Rolf M. (rmagnus)


Lesenswert?

Phlupp schrieb:
> Für das konkrete Problem, siehe Eingangspost.

Da sehe ich kein Problem. Höchstens den Versuch, es zu lösen. Wofür du 
glaubst, zwei Überladungen für const und nicht-const zu brauchen, geht 
aus dem Posting nicht hervor. Genau wie mkbit habe ich sowas noch nie 
gebraucht und auch keine Idee, wofür man es brauchen könnte.

Phlupp schrieb:
> Philosophieren würde ich eher darüber, warum man/der Compiler nicht
> unterscheidet, obwohl er es könnte.

Das hab ich bereits geschrieben. Die "constness" von dem, was du 
übergibst, hat nichts mit der der Funktionsparameter zu tun.

von Einer K. (Gast)


Lesenswert?

Rolf M. schrieb:
> Genau wie mkbit habe ich sowas noch nie
> gebraucht und auch keine Idee, wofür man es brauchen könnte.

Geht mir auch so!


Wofür brauchst du sowas?

von Hau Wech (Gast)


Lesenswert?

Hmmm ..

void fiction( somewhat unsigned_integer V )
{
 const V = 5;
 /* do code here */

}

???

Bin kein C-Coder , hacke aber ab und an in Open Source Quellen herum 
....

von Irgendwer (Gast)


Lesenswert?

Das "const" bezieht sich nur auf die erlaubte Verwendung der Variable 
innerhalb der Funktion und nicht auf das was du übergeben willst.
1
void foo(int x)
2
{
3
  while(x>0)
4
  {
5
    --x;    
6
  }
7
}
8
9
...main...
10
{
11
  foo(5);
12
13
  int x = 5;
14
  foo(x);
15
  printf("%d", x); // und jetzt darüber wundern das x immernoch 5 ist:-)
16
17
  const int x2 = 5;
18
  foo(x2);
19
}

So, und jetzt versuch das mal mit const...
Da wird der Compiler dir ganz schnell die Freundschaft kündigen und das 
sogar ganz egal ob du das mit einer Konstante oder einer Variable 
aufrufst. Die Fehlermeldung kommt ganz wo anders zustande.
1
void foo(const int x)
2
{
3
  while(x>0)
4
  {
5
    --x;    // hier kommt jetzt der Fehler:-)
6
  }
7
}
8
9
...main...
10
{
11
  foo(5);
12
13
  int x = 5;
14
  foo(x);
15
16
  const int x2 = 5;
17
  foo(x2);
18
}

von Phlupp (Gast)


Lesenswert?

Da kann ich nur sagen, man soll nicht immer von sich auf andere 
schließen..
Wie wäre es z.B. konkret mit dem Zählen gesetzter Bits im Byte (was 
einfacheres fällt mir gerade nicht ein). Ist das Byte bekannt zur 
Compile-Zeit, kann man im Extremfall die Berechnung ganz weg lassen 
(0x00). Ist die Var unbekannt, muss man alle 8 Stellen beachten - das 
ist ...uNeNdLiCh-mal soviel...


>"Parameter declarations that differ only in the presence or absence of
>const and/or volatile are equivalent. That is, the const and volatile
>type-specifiers for each parameter type are ignored."
Steht da zufällig auch, warum man das für eine gute Idee gehalten hat? 
Ignorieren hätte man es auch erst dann können, wenn es nicht mehr anders 
geht.

von Wilma Streit (Gast)


Lesenswert?

Phlupp schrieb:

> Steht da zufällig auch, warum man das für eine gute Idee gehalten hat?
> Ignorieren hätte man es auch erst dann können, wenn es nicht mehr anders
> geht.

Das const im Funktionsparameter ist lediglich eine lokale Deklaration 
als konstant. De Facto handelt es sich nach außen hin um exakt den 
gleichen Datentyp wie ohne const. Die Tatsache dass du versuchst hier zu 
überladen zeigt nur, dass du das auch nach etlichen Erklärungen nicht 
verstanden hast.
Die Frage ist nicht, warum man sich dazu entschieden hat const im 
Fkt-Kopf zu ignorieren, sondern warum man es beachten sollte. Es 
dahingehend zu ignorieren ist nur folgerichtig anhand der Bedeutung die 
es dort hat.

von M.K. B. (mkbit)


Lesenswert?

Phlupp schrieb:
> Da kann ich nur sagen, man soll nicht immer von sich auf andere
> schließen..

Man sollte anderen eine Glaskugel schenken, wenn sie einen verstehen 
sollen was man denkt. Ganz im ernst, du regst dich hier über etwas für 
die meisten hier unnötiges auf, hältst es aber nicht für notwendig und 
zu helfen, deine Gedanken nachvollziehen zu können.

Phlupp schrieb:
> Wie wäre es z.B. konkret mit dem Zählen gesetzter Bits im Byte (was
> einfacheres fällt mir gerade nicht ein). Ist das Byte bekannt zur
> Compile-Zeit, kann man im Extremfall die Berechnung ganz weg lassen
> (0x00). Ist die Var unbekannt, muss man alle 8 Stellen beachten - das
> ist ...uNeNdLiCh-mal soviel...

Wie würde das const im Übergabeparameter da weiterhelfen? Const heißt ja 
nur, dass die Variable in dem Code nicht verändert werden darf, nicht 
dass es eine Compiletimekonstante ist. Aber dafür gibt es ja schon was, 
dass du dir sicher angeschaut hast. Tipp: Es fängt mit const an.

von Phlupp (Gast)


Lesenswert?

Also für mich war die Sache nach
>Danke,
>ich hatte die Hoffnung, es gäbe eine schöne Lösung.
erledigt.

Alles weitere ist nur das 'Philosophieren'.

@ Wilma Streit: Und warum glaubst du, dass sich das nach deiner x-ten 
Widerholung ändert?! Verwandt mit Anne Fresse? Wenn du dich mit dem 
Dogma abfinden möchtest, hält dich keiner auf.

@ M.K. B.: Lies einfach nochmal meinen Eingangspost.. constexpr meinst 
du hoffentlich nicht.
>Ganz im ernst, du regst dich hier über etwas für
>die meisten hier unnötiges auf, ...
Nach dem Warum fragen und sich Aufregen sind wohl doch leicht 
verschiedene Dinge..

>...hältst es aber nicht für notwendig und
>zu helfen, deine Gedanken nachvollziehen zu können.
Nun, da ich jetzt ja sogar ein konkretes Beispiel geliefert habe, frage 
ich mich wo eine weiterführende Antwort bleibt.. Oder sollte es 
letztlich keinen Unterschied machen, ob du eine Glaskugel besitzt oder 
nicht?!?
Wie gesagt, im Eingangspost steht eigentlich schon alles (übrigens auch, 
dass es mit const nicht geht).

von Einer K. (Gast)


Lesenswert?

Phlupp schrieb:
> Wie gesagt, im Eingangspost steht eigentlich schon alles (übrigens auch,
> dass es mit const nicht geht).
Nein!
Da steht nicht was du erreichen möchtest, und vor allen Dingen nicht: 
Warum?

Bisher sieht das für mich nach einer fürchterlich dummen Idee aus.
Aber du könntest ja mal sagen, worum es sich wirklich dreht.

von Rolf M. (rmagnus)


Lesenswert?

Phlupp schrieb:
> Da kann ich nur sagen, man soll nicht immer von sich auf andere
> schließen..
> Wie wäre es z.B. konkret mit dem Zählen gesetzter Bits im Byte (was
> einfacheres fällt mir gerade nicht ein). Ist das Byte bekannt zur
> Compile-Zeit, kann man im Extremfall die Berechnung ganz weg lassen
> (0x00).

Liest du eigentlich, was andere schreiben? const heißt nicht, dass der 
Wert zur Compilezeit bekannt ist. Beispiel:
1
#include <stdio.h>
2
void myfunc(const int x)
3
{
4
    printf("Die 'Konstante' hat den Wert %d\n", x);
5
}
6
7
8
int main(int argc, char* argv[])
9
{
10
    const int i = argc;
11
    myfunc(i);
12
    return 0;
13
}

Das Programm wird (sowohl in C, als auch in C++) problemlos laufen, und 
die Werte von i und x sind zur Compilezeit unbekannt. Das const ändert 
daran nichts. Das heißt, getrennte Überladungen für const und 
nicht-const würden in dem Fall überhaupt nicht helfen.

Und ich verstehe auch nicht, warum man die Berechnung bei zur 
Compilezeit bekannten Werten weglassen können soll und was das 0x00 
bedeuten soll. Haben alle Compilezeitkonstanten den Wert 0? Oder was 
willst du damit sagen?

> Ist die Var unbekannt, muss man alle 8 Stellen beachten - das
> ist ...uNeNdLiCh-mal soviel...

Der Funktion ist sie immer unbekannt. Wäre das nicht so, dann bräuchte 
man es nicht als Parameter.

>>"Parameter declarations that differ only in the presence or absence of
>>const and/or volatile are equivalent. That is, the const and volatile
>>type-specifiers for each parameter type are ignored."
> Steht da zufällig auch, warum man das für eine gute Idee gehalten hat?

Wie schon mehrfach erwähnt, ergibt sich das automatisch. Wenn man es 
anders wöllte, bräuchte man eine zusätzliche Sonderregel für diesen 
Fall, durch die das Verhalten anders wäre, als an anderen Stellen. Und 
niemand hat das wohl großartig gebraucht, so dass das nicht 
gerechtfertigt wäre.

> Ignorieren hätte man es auch erst dann können, wenn es nicht mehr anders
> geht.

C++ ist schon kompliziert genug. Da muss man nicht noch zusätzliche 
Spezialfälle einbauen, die außer dir keiner zu brauchen scheint.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Phlupp schrieb:
> Ist das Byte bekannt zur
> Compile-Zeit, kann man im Extremfall die Berechnung ganz weg lassen
> (0x00).

Das geht aber nur, wenn die Funktion an der Aufrufstelle expandiert 
wird. Die Funktion muß also entweder always_inline oder ein Macro sein.

von M.K. B. (mkbit)


Lesenswert?

Phlupp schrieb:
> Nun, da ich jetzt ja sogar ein konkretes Beispiel geliefert habe, frage
> ich mich wo eine weiterführende Antwort bleibt..

Tut mit leid, ich bin raus. Offensichtlich hast du es nicht nötig, den 
freiwilligen Helfern hier entgegen zu kommen.

von Jan (Gast)


Lesenswert?

Es wurde schon n paar Mal erwähnt, aber bei mir hat es damals auch etwas 
gedauert...

Das const im parameter erzeugt nicht eine Funktion, der man nur 
Konstanten übergeben kann, sondern sie ist ein Versprechen der Funktion, 
dass der Parameter nicht verändert wird!

Bei per call by value übergebenen Variablen (nicht Pointer oder 
Referenzen) macht es allerdings eh keinen Unterschied..

von Vincent H. (vinci)


Lesenswert?

Phlupp schrieb:
> Steht da zufällig auch, warum man das für eine gute Idee gehalten hat?
> Ignorieren hätte man es auch erst dann können, wenn es nicht mehr anders
> geht.

Ich war noch nicht auf der Welt als function overloading Teil von C++ 
wurde, aber ich vermute dass man sich aus Gründen der Vernunft dagegen 
entschieden hat das const mitspielt.

Man stelle sich folgende Situation vor:
1
void fkt(const int) {
2
  cout << "hier?\n";
3
}
4
5
void fkt(int) {
6
  cout << "oder hier?\n";
7
}
8
9
fkt(5);

Intuitiv wäre dass die const Version mit dem Literal aufgerufen wird. 
Weil 5 aber nur vom Typ int ist würde das nie passieren... C++ ist zwar 
klassisch die Sprache mit den falschen Defaults, aber das wäre absolut 
irre.

von Vn N. (wefwef_s)


Lesenswert?

PPB schrieb:
> Das ist C++ und nicht C.

Interessant, woher beziehst du die Information, dass der TS C verwendet?

Phlupp schrieb:
>>Du möchtest constexpr:
> "a parameter cannot be declared 'constexpr'"

Tut mir leid, etwas Eigeninitiative kann man wohl doch erwarten.

Phlupp schrieb:
> ..dass "const int" ein anderer typ als "int" ist und "5" konstanter als
> "a".
> Was spräche dagegen?

Gar nix. Du verstehst nur die Sprache nicht, und solltest dir mal ein 
gutes C++-Buch zulegen.

Phlupp schrieb:
> Philosophieren würde ich
> eher darüber, warum man/der Compiler nicht unterscheidet, obwohl er es
> könnte. Es spricht schließlich nichts dagegen, es auf die 'allgemeinere'
> Variante zurückzuführen, sollte nur eine existieren.

Phlupp schrieb:
> ich hatte die Hoffnung, es gäbe eine schöne Lösung.

Verwende constexpr, dann macht der Compiler das schon ganz von selbst.

Phlupp schrieb:
> Steht da zufällig auch, warum man das für eine gute Idee gehalten hat?
> Ignorieren hätte man es auch erst dann können, wenn es nicht mehr anders
> geht.

Weil es keiner braucht, dafür gibt es (mittlerweile) constexpr.


Und da du dich ja beharrlich weigerst, constexpr zu verstehen:
1
#include <cstdint>
2
3
constexpr int factorial(const uint32_t n)
4
{
5
    return n <= 1 ? 1 : (n * factorial(n - 1));
6
}
7
8
int main()
9
{
10
    // computed by compiler
11
    const uint32_t fact_4 = factorial(4);
12
    
13
    // volatile in argument forces calculation at runtime
14
    volatile int k = 8;
15
    const uint32_t fact_8 = factorial(k);
16
}
wird zu
1
factorial(unsigned long):
2
        PUSHM.W #1, R4
3
        MOV.W   R1, R4
4
        SUB.W   #4, R1
5
        MOV.W   R12, -4(R4)
6
        MOV.W   R13, -2(R4)
7
        CMP.W   #0, -2(R4) { JNE      .L6
8
        CMP.W   #0, -2(R4) { JNE      .L2
9
        MOV.B   #1, R12
10
        CMP.W   -4(R4), R12 { JHS     .L2
11
.L6:
12
        MOV.W   -4(R4), R14
13
        ADD     #-1, R14 ; cy
14
        MOV.W   -2(R4), R15
15
        ADDC    #-1, R15
16
        MOV.W   R14, R12
17
        MOV.W   R15, R13
18
        CALL    #factorial(unsigned long)
19
        BIT.W   #0x8000, R12 { SUBC.W R13, R13 { INV.W  R13, R13
20
        MOV.W   -4(R4), R13
21
        CALL    #__mspabi_mpyi
22
        BR      #.L5
23
.L2:
24
        MOV.B   #1, R12
25
.L5:
26
        ADD.W   #4, R1
27
        POPM.W  #1, r4
28
        RET
29
main:
30
        PUSHM.W #1, R4
31
        MOV.W   R1, R4
32
        SUB.W   #10, R1
33
        MOV.W   #24, -4(R4)
34
        MOV.W   #0, -2(R4)
35
        MOV.W   #8, -10(R4)
36
        MOV.W   -10(R4), R12
37
        BIT.W   #0x8000, R12 { SUBC.W R13, R13 { INV.W  R13, R13
38
        CALL    #factorial(unsigned long)
39
        MOV.W   R12, R13 { MOV.W      R12, R14 { RPT      #15 { RRAX.W        R14
40
        MOV.W   R13, -8(R4)
41
        MOV.W   R14, -6(R4)
42
        MOV.B   #0, R12
43
        ADD.W   #10, R1
44
        POPM.W  #1, r4
45
        RET
GCC 6.2.1 für MSP430

Man beachte dass
1
const uint32_t fact_4 = factorial(4);
zu
1
MOV.W   #24, -4(R4)
2
MOV.W   #0, -2(R4)

optimiert wird.

von Peter D. (peda)


Lesenswert?

The constexpr specifier declares that it is possible to evaluate the 
value of the function or variable at compile time.
A constexpr specifier used in a function or static member variable 
(since C++17) declaration implies inline.

von Phlupp (Gast)


Lesenswert?

Ich frage mich, wie manche Leute hier so eine einfache Frage dermaßen 
aufblähen können - wohl zu viel heiße Luft..
Hier wissen einige wohl nicht, was Philosophieren bedeutet.
Bitte! lest euch nochmal gründlich den Eingangspost durch, wenn ihr euch 
das zutraut..

Also der Reihe nach:
@Arduino Fanboy D.
>Nein!
..Doch..
>Da steht nicht was du erreichen möchtest, und vor allen Dingen nicht:
>Warum?
Falsch: überladene Fkt + Unterscheidung Compilezeit-Konstante ("5") <-> 
Variable ("x").
"5" werden viele als sog. 'Zahl' erkennen und "x" als sog. 'Variable' 
und 'überladen' als überladen.
Und du so?
Und wenn du nicht weißt, was alternativ, oder Algo bedeutet, sag 
bescheid.


@ Rolf M.
>Und ich verstehe auch nicht, warum man die Berechnung bei zur
>Compilezeit bekannten Werten weglassen können soll und was das 0x00
>bedeuten soll.
0x00 -> 0b00000000, schon mal über 0en summiert?!

@ Peter D.
Dann doch lieber always inline ;). Zumindest gcc scheint das auch ohne 
Hilfe hinzubekommen. Jedoch: Sicher ist sicher.

@M.K. B.
>Tut mit leid, ich bin raus.
Na, welch ein Zufall.. Warum nur habe ich das Gefühl, du warst nie 
drin..
Du wirst uns doch nicht etwa deine meisterliche Lösung für das konkret 
gestellte Problem vorenthalten? Oder gibt es sie etwa gar nicht?
>Offensichtlich hast du es nicht nötig, den
>freiwilligen Helfern hier entgegen zu kommen.
Also wenn dir ein Danke nicht genügt, soll das dein Problem alleine 
sein.
Helfern komme ich gerne entgegen, Hatern nicht.

@ Vincent H.
>Intuitiv wäre dass die const Version mit dem Literal aufgerufen wird.
>Weil 5 aber nur vom Typ int ist würde das nie passieren... C++ ist zwar
>klassisch die Sprache mit den falschen Defaults, aber das wäre absolut
>irre.
Hmm, irgendwie kann ich deren Entscheidung noch immer nicht ganz 
nachvollziehen. Du sagst ja selbst es wäre intuitiv, ein Literal als 
const zu betrachten (btw. wer noch nie ein ..ul vergessen hat, werfe den 
1. Stein). Sehe ich auch so.
Bei & wird das genau so gemacht, bei "Kopien" wird es bewusst ignoriert.

@ vn n.
>Tut mir leid, etwas Eigeninitiative kann man wohl doch erwarten.
Wie meinen? constexpr scheint mir nicht das, was ich bräuchte (wenn es 
überhaupt ginge)!?

>Gar nix. Du verstehst nur die Sprache nicht, und solltest dir mal ein
>gutes C++-Buch zulegen.

>Weil es keiner braucht, dafür gibt es (mittlerweile) constexpr.
Na wer da wohl die Sprache nicht richtig verstanden hat.. Das 
"mittlerweile" gehört absolut nicht in Klammern.. ;)
Dennoch Danke für dein ausführliches Beispiel. Trifft aber, wie schon 
gesagt, nicht auf meinen Fall zu.

@ Peter D.
Das hilft nicht bei Überladung von pass-by-value-Funktionen und auch 
nicht bei "halb-konstanten" Funktionen.

...aber das hatten wir alles schon...


Soweit mir bekannt, sind diejenigen, die andere für dumm halten wollen, 
oft selbst nicht bereit ihr Hirn für etwas anderes als Kopfschmerzen zu 
benutzen.

von nfet (Gast)


Lesenswert?

Theoretisch wäre das was der TO möchte schon umsetzbar. Der Compiler 
trifft ja auch bei überladenen Funktionen mit und ohne constexpr die 
richtige Entscheidung. Wenn man nun ein Argument der Funktion als 
constexpr kennzeichnen würde,  müsste das immer noch klappen. Praktisch 
hatte wohl niemand Lust das zu implementieren. Daher gibt es nur 
Funktionen, die entweder ganz constexpr sind oder gar nicht.

Mir fallen trotzdem 2 Lösungen ein.
1. Template Funktionen (so wäre wohl auch die Implementierung mit 
constexpr Argumenten gelöst), mit ein bisschen TMP. Also sowas wie
foo(int x, int y) {if (is_literal(x)) templated_foo<x>(y) else ...}
Für die genaue Implementierung muss man da sicher noch hier und da ein 
bisschen rumspielen. So fit bin ich nicht in TMP.
2. Die Funktion trennen und den optimierbaren Teil in eine constexpr 
Funktion auslagern.

von Einer K. (Gast)


Lesenswert?

Phlupp schrieb:
> "5" werden viele als sog. 'Zahl' erkennen und "x" als sog. 'Variable'
> und 'überladen' als überladen.
Dass ein const Parameter nicht die Lösung sein kann, ist dir ja 
hoffentlich mittlerweile klar.
Also funktioniert das auch mit dem Überladen nicht!

Immerhin bietet dir der Gcc die Chance, eine solche Konstante zu 
erkennen.
Suche: __builtin_constant_p (exp)

von Vn N. (wefwef_s)


Lesenswert?

Phlupp schrieb:
> Wie meinen? constexpr scheint mir nicht das, was ich bräuchte (wenn es
> überhaupt ginge)!?

Dann poste doch endlich mal ein ordentliches Codebeispiel, was du 
erreichen willst, ich sehe nämlich nicht, constexpr nicht passt...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.