2012-10-15 12 views
8

miałem funkcją submitAsync który przyjął szablonie std::function jako parametr:Dlaczego GCC generuje dziwny błąd i próbuje wywołać niewłaściwą metodę, gdy argumenty szablonu są jawnie określone?

template <typename Ret, typename... Args>                                      
Future<Ret> submitAsync(const function<Ret (Args...)> &func, Args&&... args); 

jednak niejawna odliczenie szablon argument nie działa podczas mijania lambda (podobny do kwestii here, więc musiałem zrobić więcej rodzajowy funkcja, która przyjęła funkcję jako parametr szablonu, aby następnie przekazać je do pierwotnej funkcji:

template <typename Func, typename... Args> 
auto submitAsync(Func &&func, Args&&... args) -> // Line 82, where the strange error occurs 
    Future< 
     typename enable_if< 
      is_convertible< 
       Func, function<decltype(func(args...)) (Args...) > 
      >::value , decltype(func(args...)) 
     >::type 
    > { 
    typedef decltype(func(args...)) ReturnType; 
    return submitAsync<ReturnType, Args...>(function<ReturnType (Args...)>(func), forward<Args>(args)...); 
} 

To kompiluje grzywny z Clang, ale z GCC zwraca następujący błąd:

src/Scheduler.hpp: In substitution of ‘template<class Func, class ... Args> Future<typename std::enable_if<std::is_convertible<Func, std::function<decltype (func(MCServer::Scheduler::startThread::args ...))(Args ...)> >::value, decltype (func(args ...))>::type> MCServer::Scheduler::submitAsync(Func&&, Args&& ...) [with Func = int; Args = {}]’: 
src/Scheduler.hpp:91:109: required from ‘Future<typename std::enable_if<std::is_convertible<Func, std::function<decltype (func(MCServer::Scheduler::startThread::args ...))(Args ...)> >::value, decltype (func(args ...))>::type> MCServer::Scheduler::submitAsync(Func&&, Args&& ...) [with Func = MCServer::MinecraftServer::init()::<lambda()>&; Args = {}; typename std::enable_if<std::is_convertible<Func, std::function<decltype (func(MCServer::Scheduler::startThread::args ...))(Args ...)> >::value, decltype (func(args ...))>::type = int]’ 
src/MinecraftServer.cpp:237:37: required from here 
src/Scheduler.hpp:82:10: error: expansion pattern ‘#‘nontype_argument_pack’ not supported by dump_expr#<expression error>’ contains no argument packs 

To pokazuje, po pierwsze, że linie

return submitAsync<ReturnType, Args...>(function<ReturnType (Args...)>(func), forward<Args>(args)...); 

które powinny być nazywając submitAsync(const function<Ret (Args...)> &, Args&&...), jest rzeczywiście próbuje zadzwonić submitAsync(Func &&func, Args&&... args), co oczywiście nie działa jak rodzaj func były przekazywane jest int. Ostatnią część błędu też nie rozumiem, expansion pattern ‘#‘nontype_argument_pack’ not supported by dump_expr#<expression error>’ contains no argument packs, co może być błędem kompilatora (linia 82 jest główną częścią sygnatury funkcji, w której umieszczam komentarz, aby ją zaznaczyć)?

dziwo, kiedy usunąć bezpośrednimi parametrów szablonu w zaproszeniu do submitAsync, zastępując ten wiersz:

return submitAsync<ReturnType, Args...>(function<ReturnType (Args...)>(func), forward<Args>(args)...); 

z tym:

return submitAsync(function<ReturnType (Args...)>(func), forward<Args>(args)...); 

GCC kompiluje poprawnie. Dlaczego GCC wywołuje niewłaściwą funkcję, gdy podano argumenty szablonu, nawet jeśli działa poprawnie, gdy pozwala na wyprowadzenie argumentów? I czy ktoś może mi powiedzieć, jaki jest dziwny błąd na linii 82?

Edit: Zapomniałem wspomnieć, używam GCC 4.7.2

EDIT 2: solution and explanation here

+2

Ten dziwny błąd wygląda na problem z kompilatorem. Z której wersji GCC korzystasz? –

+0

O tak, zapomniałem wspomnieć, że używam GCC 4.7.2 –

+1

* "nontype_argument_pack" nie jest obsługiwany * wydaje się wskazywać, że kompilator nie obsługuje jeszcze tej konkretnej funkcji ... –

Odpowiedz

1

Po dalszych badań, zdałem sobie sprawę, że zarówno Clang i GCC bez wyraźnych parametrów szablonu nie było pracowałem tak, jak chciałem. W obu przypadkach funkcja nazywała się po prostu pierwszą funkcją, która pasowała do parametrów. Było to spowodowane przez kompilator decydujący o submitAsync, który przyjął funkcję, ponieważ parametr szablonu był lepiej dopasowany niż ten, który przyjmuje const std::function&. Działa to teraz po zmianie tego submitAsync, aby skorzystać z funkcji poprzez odniesienie:

template <typename Ret, typename... Args> 
Future<Ret> Scheduler::submitAsync(function<Ret (Args...)> func, Args&&... args) 
Powiązane problemy