I had a submitAsync function that took a template std::function as a parameter:
template <typename Ret, typename... Args> Future<Ret> submitAsync(const function<Ret (Args...)> &func, Args&&... args);
However, the implicit derivation of the template argument did not work when passing the lambda (similar to the problem here , so I had to make a more general function that took as a template parameter, then pass it to the original function:
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)...); }
This compiles using Clang, but with GCC, the following error is returned:
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
This shows, firstly, that the lines
return submitAsync<ReturnType, Args...>(function<ReturnType (Args...)>(func), forward<Args>(args)...);
which should call submitAsync(const function<Ret (Args...)> &, Args&&...) , is actually trying to call submitAsync(Func &&func, Args&&... args) , which of course does not work, since func passed int type. The last part of the error, which I also donβt understand, is expansion pattern '#'nontype_argument_pack' not supported by dump_expr#<expression error>' contains no argument packs , which may be a compiler error (line 82 is the main part of the function signature, where I put the comment to tag her)?
Oddly enough, when I remove explicit template parameters in a call to submitAsync , replacing this line:
return submitAsync<ReturnType, Args...>(function<ReturnType (Args...)>(func), forward<Args>(args)...);
with this:
return submitAsync(function<ReturnType (Args...)>(func), forward<Args>(args)...);
GCC compiles it correctly. So why does GCC call the wrong function when specifying template arguments, even if it works fine when arguments are allowed? And can anyone tell me what a strange mistake on line 82?
Edit: Forgot to mention, I'm using GCC 4.7.2
EDIT 2: solution and explanation here