[英]C++ lambda expression as an argument in function template
我需要定义一个接受集合的函数和一个函数作为输入,以进行漂亮的集合打印。 为此,我想明确指定函数的类型,以便编译器可以递归匹配,从而实现签名
template<typename T, PrettyPrinter>
std::string to_string(const std::set<T>& set, PrettyPrinter printer);
不够精确,因为编译器无法推断所需的函数对象的类型。 因此,我想使用显式输入
template<typename T>
std::string PrettyPrinting::to_string(const std::set<T>& set, std::function<std::string(const T&)> printer){
const char* separator = ", ";
const char* leftDelimiter = "{";
const char* rightDelimiter = "}"
std::string output = leftDelimiter;
if(set.begin() == set.end()) return output + rightDelimiter;
typename std::set<T>::const_iterator it = set.begin();
output += printer(*it);
for(++it; it != set.end(); it++) output.append(separator) += printer(*it);
return output + rightDelimiter;
}
这符合我的期望。 但是,我不能在另一个模板构造中使用lamba表达式
std::string to_string(const std::set<std::string>& set){
return to_string(set, [](const std::string& input){ return input; });
}
我收到一些奇怪的错误,即lambda函数不适合作为参数。 另一方面,以下代码有效
inline std::string to_string(const std::set<std::string>& set){
std::function<std::string(const std::string&)> printer = [](const std::string& input){ return input; };
return to_string(set, printer);
}
是否有任何合理的原因,为什么编译器需要显式的函数对象? 我应该指定什么类型,以便可以直接将lambda表达式写为函数参数?
Lambda和std::function<...>
是两种不同的类型。 模板参数推导不关心隐式转换。 尝试这个:
template<typename T, typename PrintLambda, typename = std::enable_if_t<std::is_convertible<PrintLambda, std::function<std::string(const T&)> >::value >>
std::string PrettyPrinting::to_string(const std::set<T>& set, PrintLambda printer);
上面通过检查PrintLambda
是否可以转换为适当的std::function
来确保其具有正确的签名。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.