2015-11-13 10 views
5

Oto minimalny przykład wywołując błąd kompilacji:Dlaczego to zastąpienie parametru szablonu variadic zawodzi? (opakowań przed stałe argumenty)

#include <utility> 
void foo(int, double, int) 
{} 

template <class... Args> 
void post_forwarder(void(*fun)(Args..., int), Args&&... aArgs) 
{ 
    fun(std::forward<Args>(aArgs)..., 5); 
} 

int main() 
{ 
    post_forwarder(foo, 6, 6.1); // Compilation error on instantiation 
    return 0; 
} 

Podejrzewam, że problem jest związany z faktem, że o zmiennej liczbie argumentów parametr szablonu jest rozszerzany w rodzaju funkcji przed wyznaczonym int parametr , ale jeśli tak jest, nie mogę znaleźć dobrego uzasadnienia.

Błąd zgłoszony przez Clang 3.6 jest:

error: no matching function for call to 'post_forwarder' 
note: candidate template ignored: failed template argument deduction 
+1

Czy możesz zgłosić błąd? To było by pomocne. – lodo

+1

Na marginesie, wydedukowałem 'Args && ... przekierowanie do wskaźnika funkcji oczekiwanego' Args ... 'nie jest dobrym planem. Tylko upewniając się, że o tym wiesz. – Yakk

+0

@Yakk Muszę przyznać, że mogłem naprawdę użyć więcej szczegółów dotyczących punktu, który wychowujesz :) –

Odpowiedz

7

Argument odliczenie nie tutaj:

template <class... Args> 
void post_forwarder(void(*fun)(Args..., int), Args&&... aArgs) 
          // ^^^^^^^ 

dla ogólnej zasady, że parametr opakowania muszą być w końcu się wywnioskować. Najczęstszym rozwiązaniem jest zawijanie go do kontekstu bez dedukcji, więc odliczanie nie jest nawet podejmowane:

template <typename T> 
struct identity { 
    using type = T; 
}; 

template <class... Args> 
void post_forwarder(void(*fun)(typename identity<Args>::type..., int), Args&&... aArgs) 
{ 
    fun(std::forward<Args>(aArgs)..., 5); 
} 
+0

Cóż, technicznie rzecz biorąc, pierwsze "Args ..." jest już w nie dedukowanym kontekście. –

+1

@ T.C. Tak, ale teraz jest to ** super ** nie wydedukowany kontekst. [Również, nie mam pełnego wyjaśnienia] – Barry

+0

http://stackoverflow.com/questions/26885239/whats-the-point-of-boostmplidentityttype-here. Jako sidenote naprawdę wolałbym pseudonim "tożsamości" w tych kontekstach, np. 'Dont_deduce', więc nawet jeśli nie rozumiem mechanizmu przynajmniej wiem, jaki jest cel. –

0

Edit: Przepisany odpowiedź:

Formularz Args..., int nie pozwala wywnioskować Args....

+0

Jesteś pewien? Istnieje wyraźne ostatnie 'int' w' zabawnych' sygnaturach, spodziewałbym się, że ograniczy on dedukcje 'Args ...' do pierwszych 2 parametrów. –

1

to działa:

template <class F, class... Args> 
void post_forwarder(F f, Args&&... aArgs) { 
    f(std::forward<Args>(aArgs)..., 5); 
} 

LIVE DEMO

+1

To działa, ale pytanie jest, aby spróbować zrozumieć, dlaczego proponowany minimalny przykład nie działa? (Ponieważ jest pobierany z bardziej złożonego systemu, w którym proponowana alternatywa nie może zastąpić oczekiwanej funkcjonalności). –

+0

@AdN Przepraszamy, miałem kilka ważnych rzeczy i nie mogłem odpowiedzieć. Jest to kontekst, którego nie można odliczyć, dlatego się nie udaje. Ale już masz odpowiedź. – 101010

Powiązane problemy