gpt4 book ai didi

c++ - 为什么 GCC 会在显式指定模板参数时产生奇怪的错误并尝试调用错误的方法?

转载 作者:可可西里 更新时间:2023-11-01 17:59:40 31 4
gpt4 key购买 nike

我有一个函数 submitAsync它接受了一个模板化的 std::function作为参数:

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

但是,隐式模板参数推导在传递 lambda 时不起作用(类似于问题 here ,所以我不得不制作一个更通用的函数,接受该函数作为模板参数,然后将其传递给原始函数:

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:solution and explanation here

最佳答案

经过进一步测试,我意识到没有显式模板参数的 Clang 和 GCC 实际上并没有像我希望的那样工作。在这两种情况下,该函数只是将自身作为第一个适合参数的函数进行调用。这是由于编译器决定将函数作为模板参数的 submitAsync 比采用 const std::function& 的匹配更好。在更改 submitAsync 以通过引用获取函数后,它现在工作正常:

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

关于c++ - 为什么 GCC 会在显式指定模板参数时产生奇怪的错误并尝试调用错误的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12900578/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com