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
Ten dziwny błąd wygląda na problem z kompilatorem. Z której wersji GCC korzystasz? –
O tak, zapomniałem wspomnieć, że używam GCC 4.7.2 –
* "nontype_argument_pack" nie jest obsługiwany * wydaje się wskazywać, że kompilator nie obsługuje jeszcze tej konkretnej funkcji ... –