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
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. 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?
Lambdas and std::function<...>
are two different types. 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
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.