【问题标题】:std::function template param can not be deduced无法推断 std::function 模板参数
【发布时间】:2018-07-08 16:43:50
【问题描述】:

我正在编写类似下面的代码

#include <functional>

template <typename Type>
void foo(const std::function<void(const Type&)> & handler) {}

void goo (const int&){}

int main() {
    foo([](const int&){});
    foo(goo);
}

很遗憾,由于以下错误,它拒绝在(clang 6.0.0 和 gcc 8.1.1)上编译

candidate template ignored: could not match 'function<void (const type-parameter-0-0 &)>' against '(lambda at test3.cpp:13:9)'
candidate template ignored: could not match 'function<void (const type-parameter-0-0 &)>' against '(lambda at test3.cpp:13:9)'

是否有可能以某种方式强制它正确推断出Type

【问题讨论】:

  • 使用std::function作为论据吗?如果您仅查看带有可调用参数的所有标准库函数(就像许多algorithm functions一样),它们对可调用类型使用单个模板参数,在您的情况下可能类似于@ 987654326@
  • 之后,我将这些操作存储在列表中,以便稍后调用每个类型。
  • @majkrzak 您可以强制构造std::function 对象。 foo(std::function&lt;void(const int&amp;)&gt;(&amp;goo));
  • 有什么阻止您将模板参数添加到调用中吗?它为我编译,然后:foo&lt;int&gt;([](const int&amp;){});
  • @Someprogrammerdude 最常见的问题可能是“如何以通用方式存储 Callable”。

标签: c++ templates c++17 std-function template-argument-deduction


【解决方案1】:

您标记了 C++17,因此您可以使用 std::function 的演绎指南。

你可以尝试以下方法

template <typename F,
          typename Type = typename decltype(std::function{std::declval<F>()})::argument_type>
void foo (F f)
 {
 }

我知道 argument_type 在 C++17 中已弃用,但您可以用简单的自定义模板替换它。

举例

template <typename>
struct firstArg;

template <typename R, typename A0, typename ... As>
struct firstArg<std::function<R(A0, As...)>>
 { using type = A0; };

foo()可以写成

template <typename F,
          typename FUNC = decltype(std::function{std::declval<F>()}),
          typename Type = typename firstArg<FUNC>::type>
void foo (F f)
 {
 }

这样,可调用的f 不是std::function,而是原始类型(这可能更好或更糟,具体取决于您的具体要求);如果您在std::function 中需要它,您可以在foo() 函数中使用再次推导指南或FUNC 类型获得它

template <typename F,
          typename FUNC = decltype(std::function{std::declval<F>()}),
          typename Type = typename firstArg<FUNC>::type>
void foo (F f)
 {
   FUNC fnc{f};
 }

【讨论】:

  • 谢谢,这似乎是我需要的
  • @majkrzak - 回答有所改进
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-18
相关资源
最近更新 更多