std::function 无法推导模板参数
std::function template param can not be deduced
我正在编写如下代码
#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
?
您标记了 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};
}
我正在编写如下代码
#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
?
您标记了 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};
}