简体   繁体   English

C ++ lambda表达式作为函数模板中的参数

[英]C++ lambda expression as an argument in function template

I need to define a function that takes a set and a function as input to do the pretty printing of sets. 我需要定义一个接受集合的函数和一个函数作为输入,以进行漂亮的集合打印。 For that matter I would like to explicitly specify the type of the function so that the compiler could recursive matching and thus the signature 为此,我想明确指定函数的类型,以便编译器可以递归匹配,从而实现签名

template<typename T, PrettyPrinter>
std::string to_string(const std::set<T>& set, PrettyPrinter printer);

is not precise enough, as the compiler cannot infer the type of a function object needed. 不够精确,因为编译器无法推断所需的函数对象的类型。 So instead, I would like to use explicit typing 因此,我想使用显式输入

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

This does what I expect. 这符合我的期望。 However, I cannot use lamba expression in another template construction 但是,我不能在另一个模板构造中使用lamba表达式

std::string to_string(const std::set<std::string>& set){
    return to_string(set, [](const std::string& input){ return input; });
}

I get some weird error that lambda function is not appropriate argument. 我收到一些奇怪的错误,即lambda函数不适合作为参数。 On the other hand, the following code works 另一方面,以下代码有效

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

Is there any rational reasons why does the compiler need an explicit function object? 是否有任何合理的原因,为什么编译器需要显式的函数对象? What should I specify as a type so that I could write lambda expressions directly as function arguments? 我应该指定什么类型,以便可以直接将lambda表达式写为函数参数?

Lambdas and std::function<...> are two different types. Lambda和std::function<...>是两种不同的类型。 Template argument deduction does not care about implicit conversions. 模板参数推导不关心隐式转换。 Try this: 尝试这个:

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

The above ensures that PrintLambda has the right signature by checking if it is convertible to the appropriate std::function . 上面通过检查PrintLambda是否可以转换为适当的std::function来确保其具有正确的签名。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM