C++ Fehler: invalid initialization of non-const reference

Gast #2623451
Lesenswert?

Folgender Code compiliert nicht:

1
static int*& test()
2
{
3
    static int x[] = {1, 1, 2, 3, 5};
4
    return x; // error!
5
}

Der Compiler meldet hier
1
invalid initialization of non-const reference of type 'int*&' from a temporary of type 'int*'

Dies verstehe ich nicht. Meines Erachtens ist dieser Code in Ordnung, da 
x keine auto Variable vom Stack ist, sondern static ist.

Was ist hier das Problem?
Gast #2623482
Lesenswert?

> bei c++ wird x erst beim aufruf von test initialiert. Das geht scheinbar
> nicht bei arrays. Wenn du das als C übersetzt dann sollte es gehen weil
> es es vor main macht.

Folgendes geht dann wieder
1
static int*& test2()
2
{
3
    static int* x;
4
    return x;
5
}

Aber auch folgendes:
1
static int* test2()
2
{
3
    static int x[] = {1, 1, 2, 3, 5};
4
    return x;
5
}

Deshalb vermute ich, dass die initialisierung von Array nicht das 
Problem ist.


> Wozu soll das & gut sein?

Ich möchte eine Referenz auf den Zeiger.
#2623492
Lesenswert?

Vielleicht hast du sowas vor:
1
static int*& test()
2
{
3
    static int feld[] = {1, 1, 2, 3, 5};
4
    static int *x = feld;
5
    return x; // jetzt hoffentlich ohne error!
6
}

Wobei mir momentan aber noch die Phantasie fehlt, wozu das gut sein 
soll, aber das kann auch an mir liegen.
#2623502
Lesenswert?

Klaus schrieb:
>> Vielleicht hast du sowas vor:static int*& test()
>> {
>>     static int feld[] = {1, 1, 2, 3, 5};
>>     static int *x = feld;
>>     return x; // error!
>> }
>
> Danke, das ist die Lösung! :)

Blos für was?
Was bringt dir ein Zeiger auf einen Zeiger der auf das Array zeigt.
Wo ist der Vorteil davon gegenüber einfach feld als int * zurückzugeben?

Mir fehlt wie auch Klaus die Fantasie wozu deine Lösung gut sein könnte.
Gast #2623514
Lesenswert?

Okay, der Code war eine vereinfachte Form des eigentlichen Problems. Bei 
diesem geht es um eine Template-Klasse mit folgenden Konstruktor:
1
template<class T, int S>
2
class Tree
3
{
4
    public:
5
        Tree(Node<T> (& objects)[S]);
6
    // ...

Nun denke ich kann man mit etwas Phantasie das Problem erahnen :)
#2623558
Lesenswert?

Klaus schrieb:
> Okay, der Code war eine vereinfachte Form des eigentlichen Problems. Bei
> diesem geht es um eine Template-Klasse mit folgenden Konstruktor:
>
>
1
> template<class T, int S>
2
> class Tree
3
> {
4
>     public:
5
>         Tree(Node<T> (& objects)[S]);
6
>     // ...
7
>
>
> Nun denke ich kann man mit etwas Phantasie das Problem erahnen :)

Nicht wirklich.
Das erklärt immer noch nicht, warum die Funktion eine Referenz lieferen 
muss, und nicht einfach nur die Adresse des static Arrays.
Und auch hier in deinem Template frag ich mich, was die Referenz an 
dieser Stelle verloren hat. Der Konstruktor übernimmt sowieso ein Array 
und Arrays werden per Pointer übergeben. Die [S] Angabe ist nichts 
anderes als syntaktischer Zucker, eine andere Schreibweise für einen 
Pointer. Die Referenz bewirkt hier IMHO nichts (*), ausser das sie alles 
syntaxmässig komplizierter macht.


Das hier ....
1
static int* const & test()
2
{
3
    static int x[] = {1, 1, 2, 3, 5};
4
    return x; // error!
5
}
... sollte die Lösung für dein ursprüngliches Problem sein. Aber warum 
da eine Referenz ins Spiel kommen soll, ist auch mir immer noch unklar.


(*) soll bedeuten: Ich sehe nicht, aus welchem Grund hier überhaupt eine 
Referenz sein sollte, bzw. warum man sie hier braucht oder welchen Zweck 
die Referenz hier erfüllen würde. Kann natürlich sein, dass ich einfach 
nur nicht die zündende Idee erkannt habe.

Kann es sein, dass du da einen Trugschluss hast, und der Meinung bist, 
bei ....
1
void foo( int a[] )
2
{
3
  ...
4
}

würde tatsächlich das komplette Array während des Parameter Passings 
umkopiert? Wenn ja, dann muss ich dich enttäuschen. Diese Schreibweise 
(egal ob da jetzt noch eine Arraygröße angegeben ist oder nicht), ist 
nur eine alternative Schreibweise für
1
void foo( int * a )
2
{
3
  ...
4
}

Mehr steckt da nicht dahinter. Arrays werden IMMER per 'Pointer auf das 
erste Argument' übergeben, egal welche Schreibweise du benutzt.
#2623860
Lesenswert?

Klaus schrieb:
> Ich möchte eine Referenz auf den Zeiger.

Was für einen Zeiger? x ist kein Zeiger, sondern ein Array. Also muß der 
Compiler einen temporären Zeiger anlegen, der auf den Anfang des Arrays 
zeigt. Und mit dem versuchst du, deine Referenz zu initialisieren, was 
nicht erlaubt ist. Deshalb die Fehlermeldung:

Klaus schrieb:
> invalid initialization of non-const reference of type 'int*&' from a
> temporary of type 'int*'


Was auch geht, aber ähnlich sinnfrei wäre, ist, gleich eine Referenz auf 
das Array zurückzugeben:
1
static int (&test())[5]
2
{
3
    static int x[] = {1, 1, 2, 3, 5};
4
    return x;
5
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren