C++ lambda 表达式作为函数模板中的参数
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 表达式编写为函数参数?
Lambdas和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
来确保它具有正确的签名。
相关文章:
- 当函数模板参数是具有默认参数的类模板时,函数模板参数的推导如何执行
- 具有常量引用参数的函数模板专用化
- 使用可变参数函数作为模板参数
- std::span<const T> 作为函数模板中的参数
- 如何在C++中伪造虚拟可变参数函数模板?
- C++ std::functional 中的可变参数函数模板
- 可变参数函数模板不能很好地使用 std::function 作为参数
- 三个参数函数模板令人困惑的示例
- 父可变参数函数模板专门用于子级
- C++如何将可变参数函数模板的参数包 -> 包装到 lambda 中
- 将函数传递给可变参数函数模板
- 为什么可变参数函数模板中的这个 constexpr 不是常数?
- 将多个初始值设定项列表传递到可变参数函数模板时遇到问题
- 依赖类型不明确的 c++11 可变参数函数模板重载是否不明确
- 操作可变参数函数模板的函数参数
- C++11 中的非类型可变参数函数模板
- 将可变参数函数模板的每个参数传递给返回void的函数
- 包扩展不在最后一个参数中的可变参数函数模板
- 将可变参数函数模板参数存储到联合向量中的最有效方法
- Clang 和 GCC 在解决可变参数函数模板重载时的行为不同