submitAsync
テンプレートstd::function
をパラメーターとして受け入れる関数がありました。
template <typename Ret, typename... Args>
Future<Ret> submitAsync(const function<Ret (Args...)> &func, Args&&... args);
ただし、ラムダを渡すときに暗黙的なテンプレート引数の推定が機能していませんでした (ここでの問題に似ているため、関数をテンプレート パラメーターとして受け入れる、より一般的な関数を作成し、それを元の関数に渡す必要がありました。
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)
タイプが であるため、もちろん機能しません。私も理解していないエラーの最後の部分は、おそらくコンパイラのバグである可能性があります (行 82 は、関数の署名の主要部分であり、マークを付けるためにコメントを付けた場所です)。func
int
expansion pattern ‘#‘nontype_argument_pack’ not supported by dump_expr#<expression error>’ contains no argument packs
奇妙なことに、 への呼び出しで明示的なテンプレート パラメータを削除すると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を使用しています
EDIT 2:解決策と説明はこちら