2013-04-25 25 views
6

Najprostszym sposobem na to pytanie jest z jakiegoś kodu:Obsada wskaźnik do tablicy o stałym rozmiarze w instrukcji return

struct Point 
{ 
    int x; 
    int y; 
    int z; 

    int* as_pointer() { return &x; }  // works 
    int (&as_array_ref())[3] { return &x; } // does not work 
}; 

as_pointer kompiluje, as_array_ref nie. Wydaje się, że obsada jest w porządku, ale nie mogę znaleźć odpowiedniej składni. Jakieś pomysły?

+1

Czy chcesz, aby kompilator udawał, że 'x' jest w rzeczywistości tablicą trzech' int'ów? Nie ma żadnej gwarancji, że to zadziała; kompilatory mogą dodawać dopełnienie między elementami danych w sposób inny niż ten, w którym układają tablice. –

Odpowiedz

7

Uważam, że typy tablicy są łatwiejsze do czynienia z typedef:

typedef int ints[3]; 

wówczas as_array_ref musi być napisany tak, że &as_array_ref() == &x.

następujące składnie są możliwe:

  1. zwykły C-style cast z int* do ints*:

    ints& as_array_ref() { return *((ints*)(&x)); }

  2. C++ stylu reinterpret_cast (sugerowane przez @Mike Seymour - patrz także jego odpowiedź). Jest często uważane za lepsze praktyki w C++:

    ints& as_array_ref() { return *reinterpret_cast<ints*>(&x); }

  3. Odlewanie z int& do ints& który jest nieco krótszy, ale (dla mnie) mniej intuicyjne:

    ints& as_array_ref() { return reinterpret_cast<ints&>(x); }

+0

To działa, dziękuję! Więc nie pozwolę sobie zaakceptować przez kolejne 3 minuty ... –

+0

Fajnie, cieszę się, że mogę pomóc;) – Antoine

+2

Wolałbym zobaczyć styl "reinterpretacji" w C++, aby było bardziej oczywiste, że dzieje się coś podejrzanego. Odlewy w stylu C są niebezpieczne i trudne do wyszukania. –

2

I pomyśl, że to, co próbujesz zrobić, byłoby łatwiejsze (i bardziej przejrzyste/czystsze) w związku.

+0

Również bardzo dobra sugestia, dzięki. Zwykle ich unikam, więc ta myśl nawet nie przyszła mi do głowy! –

+0

Nie jestem pewien czy jest czystszy: w obu przypadkach, gdy pola strukturalne i tablice będą miały inne wypełnienie/wyrównanie, nie będzie działać. Więc jeśli się nie mylę, oba rozwiązania są niebezpieczne. – Antoine

4

Obsada trzeba reinterpretacji odwołanie do zmiennej jako odniesienie do tablicy brzmi:

reinterpret_cast<int(&)[3]>(x); 

Należy pamiętać, że stosując ten daje niezdefiniowanej zachowań; prawdopodobnie będzie działał przy każdej rozsądnej implementacji, ale nie ma gwarancji, że nie będzie dopełnienia pomiędzy członkami klasy, podczas gdy tablice nie są wypełnione.

Powiązane problemy