【问题标题】:Template deduction on function with variadic template arguments带有可变模板参数的函数的模板推导
【发布时间】:2021-07-09 15:28:23
【问题描述】:

我正在尝试编写一种任务图。当我放置新任务时,我希望能够一次添加不同的数量并获得一个包含每个添加任务的句柄的元组。

我已经为一项任务编写了一个基本案例,并使用调用基本案例的可变参数模板参数进行重载。

template<typename Task>
node<Task> emplace(Task&& task) {
  return node<Task>{std::move(task)};
}

template <typename... Tasks, std::enable_if_t<(sizeof...(Tasks) > 1)>>
auto emplace(Tasks&&... tasks) {
  return std::make_tuple(emplace(std::forward<Tasks>(tasks))...);
}

当我现在完成一项任务时

emplace([](){ something cool; });

我没有收到错误,但是当我添加两个或更多任务时

emplace(
  [](){ task a; },
  [](){ task b; }
);

我收到一条错误消息,提示 template argument deduction/substitution failed

【问题讨论】:

    标签: c++ templates variadic-templates


    【解决方案1】:

    std::enable_if_t&lt;(sizeof...(Tasks) &gt; 1)&gt; 只是void(当它存在时)。所以你的模板是template &lt;typename... Tasks, void&gt; whatever。所以你有一个void 类型的非类型模板参数。祝你好运。

    您真正想要的是typename = std::enable_if_t&lt;(sizeof...(Tasks) &gt; 1)&gt;,这是一个类型模板参数,其默认值可能会或可能不会被 SFINAE 删除。

    【讨论】:

    • std::enable_if_t&lt;(sizeof...(Tasks) &gt; 1), bool&gt; = truetypename = std::enable_if_t&lt;(sizeof...(Tasks) &gt; 1)&gt; 更适合替代std::enable_if_t&lt;(sizeof...(Tasks) &gt; 1)&gt;。它可以更好地处理超载极端情况。
    • @Yakk-AdamNevraumont 不确定您指的是哪些极端情况,您能解释一下吗?
    • @n-1-8 如果您使用 SFINAE 的候选重载超过 2 个,则您的重载会导致冲突(两者都有 typename 字段,一个具有无效默认值) ,而 NTTI 没有(只有一个有 bool NTTI 字段)
    • @Yakk-AdamNevraumont hmm 如果另一个有非类型 bool 参数怎么办?
    • @Yakk - AdamNevraumont 谢谢,你的建议奏效了。如果您将其作为答案发布并可能添加一些解释,我可以将其标记为已接受的答案:)
    猜你喜欢
    • 2013-09-14
    • 1970-01-01
    • 2014-09-08
    • 1970-01-01
    • 2020-06-05
    • 1970-01-01
    • 2012-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多