2011-02-07 5 views
5

Próbuję utworzyć wygodne opakowanie C++ wokół starego C-API, które używa nieprzejrzystego typu danych. Jest jedna konkretna funkcja C, która przyjmuje ciąg formatu, wraz ze zmienną liczbą argumentów za pomocą obiektów C <stdarg.h>. Jako część mojego opakowania, chcę móc przekazać dowolną liczbę argumentów (w tym obiektów C++) do tej funkcji. Ponieważ jednak obiektynie mogą pracować z danymi innymi niż POD, stworzyłem funkcję konwersji szablonowej, która konwertuje obiekty C++ (takie jak std::string) na odpowiedniki POD.Rozpakowywanie listy argumentów za pomocą szablonu Variadic

Pomyślałem, że cała ta sprawa będzie łatwym ćwiczeniem przy użyciu szablonów variadycznych w C++ 0x, ale mam trudności z ustaleniem, jak napisać tę funkcję w sposób, który prawidłowo rozwija pakiet argumentów, podczas stosowania mojej funkcji konwersji do każdy argument.

Co mam tak daleko jest:

template <class T, class... Args> 
    void apply(OPAQUE* object, const char* fmt_string, T&& val, Args&&... args) 
    { 
     apply(object, fmt_string, Convert(val), args...); 
    } 

    template <class... Args> 
    void apply(OPAQUE* object, const char* fmt_string, Args&&... args) 
    { 
     C_API_Function_Call(object, fmt_string, args...); 
    } 

Oczywiście, to nie działa, ponieważ rekurencyjne wywołanie funkcji nigdy nie rozpakowuje Args..., więc po prostu recurses aż do przepełnienia stosu. Nie mogę wymyślić, jak sprawić, aby rozpakowanie argumentów podczas również przekazywanie bieżącego argumentu do funkcji Convert, a następnie rekurencyjnie przekazywanie wzdłuż wyniku.

Czy jest to w ogóle możliwe?

Odpowiedz

25

myślę, że trzeba tę samą składnię jak podczas zrobić idealny do korespondencji:

template <class... Args> 
void apply(OPAQUE* object, const char* fmt_string, Args&&... args) 
{ 
    C_API_Function_Call(object, fmt_string, Convert(std::forward<Arg>(args))...); 
} 

wielokropka ... może być umieszczony po prawej stronie wyrażenia zawierającego pakiet argumentów, a nie tylko bezpośrednio u prawo do samego pakietu argumentów.

Więc:
func (args ...) rozwijać się func (arg1, arg2, arg3, [...], argN)
func (args) ... rozwiń do func (ARG1) func (arg2), [...], func (argN)

+2

Nie wiem, dlaczego PO jeszcze nie zmienił swojej opinii i nie przyjął tej odpowiedzi. Obecnie zaakceptowana jest oczywiście błędna, a twoja jest prawidłowa. +1 Wiwaty. –

-1

W tej chwili szkic C++ 0x nie zapewnia żadnego rozwiązania. Ponieważ problem jest podobny do rozwijania krotek, możesz przeczytać this discussion i napisać podobną funkcję rozwijania.