std :: function template param无法推断

时间:2018-07-08 16:43:50

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

我正在研究类似下面的代码

app.module

不幸的是,由于以下错误,它拒绝在clang 6.0.0和gcc 8.1.1上进行编译

#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);
}

是否有可能以某种方式强迫其正确推断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)'

1 个答案:

答案 0 :(得分:5)

您标记了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};
 }