2012-11-06 12 views
7

Nie wiem, czy to, co mam, to błąd kompilatora, czy też po prostu nie znam składni tego, co próbuję zrobić. Wyobraźmy sobie funkcję, która trwa od 2 referencje tablicy:Jaka jest składnia parametrów odniesienia tablicy szablonów variadic?

void takeArrays(const char (&str1)[4], const char (&str2)[4]) { 
} 

To kompiluje dobrze, gdy nazywa się:

takeArrays("foo", "bar"); 

Dlaczego miałbym to zrobić? Ponieważ przekazanie const char* traci informacje o rozmiarze literału ciągu znaków i jest to ważne dla tego, co robię.

Tym, co naprawdę chcę zrobić, jest przekazanie zmiennej liczby referencji tablicowych. Tutaj sprawy stają się nieco brzydkie (robi się coraz gorzej). I naiwnie próbowałem:

template<typename... Args> 
void takeArrays(const char (&Args... strs)[4]) { 
} 

I got "error: variable or field ‘takeArrays’ declared void" i "error: expected primary-expression before ‘const’" (GCC 4.6). Więc próbowałem to:

template<typename... Args> 
void takeArrays(const char (&(Args... strs))[4]) { 
} 

I got "no matching function for call to ‘takeArrays(const char [4], const char [4])’" i "candidate is template<class ... Args> void takeArrays(const char (& (*)(Args ...))[4])". Co jest nieczytelne, ale wydaje się bliskie temu, co chcę. Próbowałem wielu odmian i nie mogę tego zmusić do kompilacji.

Zakładając, że jest to właściwa droga do napisania powyższego, co naprawdę chcę zrobić to zadzwonić:

takeArrays("foo", "foobar", "longerstring"); 

I dostać o zmiennej liczbie argumentów listę tablic o różnych rozmiarach, czyli wywołanie powyżej powinien zostać rozszerzony przez kompilator do:

void takeArrays(const char (&str1)[4], const char (&str2)[7], 
       const char (&str3)[13]); 

który był pierwszym think Próbowałem robić, a moja próba była coś takiego:

template<size_t... Sizes> 
void takeArrays(const char (&strs)[Sizes]...); 

Nie trzeba dodawać, że otrzymałem jedynie komunikaty o błędach. Jestem świadomy, że to, co próbuję zrobić, jest trochę szalone, ale naprawdę chcę wiedzieć, czy to możliwe, a jeśli tak, to jaka jest właściwa składnia. Z góry dziękuję.

Odpowiedz

9

Składnia zmiennej liczbie argumentów macierze tego samego typu elementu jest:

template<size_t... Sizes> 
void takeArrays(const char (&...args)[Sizes]); 

ten jest podobny do ogólnego o zmiennej liczbie argumentów składni odniesienia const:

template<typename... Args> 
void takeArrays(const Args &...args); 

łatwy sposób, aby pamiętać, że wielokropek przechodzi bezpośrednio przed nazwą parametru.

+0

Tak, to działało. Dzięki! Zapamiętam elipsę przed trikiem nazwy parametru. Z ciekawości, jak mam napisać oryginalne parametry tego samego rozmiaru? Próbowałem 'szablon void takeArrays (cont char Args (& ... args ([4])' i 'const char (Args & ... args) [4]' i te nie –

+5

@ ÁtilaNeves Które nie mogą być stworzone do pracy z tego samego powodu, dla którego nie możesz napisać szablonu funkcji variadic biorąc wiele 'int's:' szablon void foo (int ... i/* nie działa: brak pakietu do rozwinięcia tutaj * /); '. Zazwyczaj obejściem byłoby zezwolenie na tablice o tym samym rozmiarze z innym typem elementu, np.' szablon void foo (T (& ... args) [Size]); '. Możesz opcjonalnie dodać' static_assert', aby wymusić, że wszystkie 'T' są' const char'. –

Powiązane problemy