考虑以下代码
template<typename T>
T modify(const T& item, std::function<T(const T&)> fn)
{
return fn(item);
}
当尝试使用它时,因为modify(5, [](const int& i){return 10*i;});
它无法编译
无法推导
'std::function<T(const T &)>
来自的模板参数lambda
我知道编译器无法T
从lambda推论出,因为lambda不是std::function
,但是还不是T
从推导得出的5
?
我可以用克服它
template<typename T, typename F>
T modify(const T& item, const F& functor)
{
return functor(item);
}
之前的示例可以针对该示例进行编译,但是我认为它不太直观。有没有办法让函数参数保留std::function
并自动从中推导出它的模板参数item
?
您基本上想做的是防止扣减的发生。如果发生模板推导,则它将失败(因为lambda不是std::function<>
-T
从第一个自变量推论的没关系,推论必须在作为推论上下文的每个自变量中都成功)。防止推论的方法是将整个参数放在非推论上下文中,最简单的方法是将类型放入嵌套名称说明符中。我们创建这样的类型包装器:
template <class T> struct non_deduce { using type = T; };
template <class T> using non_deduce_t = typename non_deduce<T>::type;
然后将类型包装在其中:
template<typename T>
void foo(const T& item, std::function<void(T)> f);
template<typename T>
void bar(const T& item, non_deduce_t<std::function<void(T)>> f);
foo(4, [](int ){} ); // error
bar(4, [](int ){} ); // ok, we deduce T from item as int,
// which makes f of type std::function<void(int)>
但是请注意:
template <typename T, typename F>
void quux(const T&, F );
的可读性并没有真正提高。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句