我有一个submitAsync
接受模板std::function
作为参数的函数:
template <typename Ret, typename... Args>
Future<Ret> submitAsync(const function<Ret (Args...)> &func, Args&&... args);
但是,在传递 lambda 时,隐式模板参数推导不起作用(类似于此处的问题,因此我必须创建一个更通用的函数,将函数作为模板参数接受,然后将其传递给原始函数:
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)...);
}
使用 Clang 可以很好地编译,但使用 GCC 返回以下错误:
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
这首先表明
return submitAsync<ReturnType, Args...>(function<ReturnType (Args...)>(func), forward<Args>(args)...);
这应该是调用submitAsync(const function<Ret (Args...)> &, Args&&...)
,实际上是试图调用submitAsync(Func &&func, Args&&... args)
,这当然不起作用,因为func
被传递的类型是int
。错误的最后一部分我也不明白,expansion pattern ‘#‘nontype_argument_pack’ not supported by dump_expr#<expression error>’ contains no argument packs
可能是编译器错误(第 82 行是函数签名的主要部分,我在其中添加了注释来标记它)?
奇怪的是,当我删除调用中的显式模板参数时submitAsync
,替换这一行:
return submitAsync<ReturnType, Args...>(function<ReturnType (Args...)>(func), forward<Args>(args)...);
有了这个:
return submitAsync(function<ReturnType (Args...)>(func), forward<Args>(args)...);
GCC 正确编译它。那么,为什么 GCC 在指定模板参数时调用错误的函数,即使它在允许推断参数时工作正常?谁能告诉我第 82 行的奇怪错误是什么?
编辑:忘了提,我使用的是 GCC 4.7.2
编辑2:这里的解决方案和解释