Reputation: 12431
I'm trying to define a function func()
, which returns a std::string
.
template<typename T = std::string, template<typename> typename F = decltype([](const T &t){return t;})>
std::string func(const T &t){
F f;
return f(t);
}
As you see, what I'm trying to do is to pass a lambda as the template parameter so that I can call the function func()
like this:
func<int, decltype([](int a){return std::to_string(a);})>(2);
Also, I set the values by default for the template parameters so that I can call it like this:
func<>("abc");
However, the code above gave me an error:
<source>:39:54: error: expected unqualified-id before 'decltype'
39 | template<typename T, template<typename> typename F = decltype([](const T &t){return t;})>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:39:54: error: invalid default argument for a template template parameter
<source>:39:54: error: expected '>' before 'decltype'
BTW, the version of my C++ is C++11.
Upvotes: 3
Views: 814
Reputation: 66230
In C++11? With a lambda as template parameter?
Given that a lambda (before C++20) can't be used in an unevaluated context (so in a decltype()
) and can't be default constructed, I don't see a way.
The best I can imagine, in C++11, to reproduce something similar is something as follows
template <typename T, typename F = std::function<std::string(T const &)>>
std::string func (T const & t, F f = [](const T &t){return std::string{t};})
{ return f(t); }
that you can call with only the first argument
func("abc");
given that you accept the default lambda (but is saved as a std::function
).
You can also pass another lambda, if you don't like the default one
func(1, [](int const &){ return "one"; });
but as a traditional argument, not as template parameter.
Upvotes: 1
Reputation: 1350
In C++11 you can't have a lambda expression in an un-evaluated context, so you'd have to implement this differently I think.
C++20 added this feature, so here's a sample that will compile and run in C++20.
#include <iostream>
#include <string>
template<typename T = std::string, typename F = decltype([](const T &t)->std::string{return t;})>
std::string func(const T &t){
F f;
return f(t);
}
int main() {
// convert int to string
std::cout << func<int, decltype([](int a){return std::to_string(a);})>(2) << std::endl;
// take float parameter, but just ignore the parameter
std::cout << func<float, decltype([](float a){return "ignore the param";})>(2.2) << std::endl;
// default lambda
std::cout << func("abc") << std::endl;
return 0;
}
Upvotes: 1